-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.xml
571 lines (274 loc) · 353 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>面试题</title>
<link href="2021/05/11/frontend/mian-shi-ti/"/>
<url>2021/05/11/frontend/mian-shi-ti/</url>
<content type="html"><![CDATA[<h3 id="美团"><a href="#美团" class="headerlink" title="美团"></a>美团</h3><h4 id="一面"><a href="#一面" class="headerlink" title="一面"></a>一面</h4><p>1.实现 hasProperty(o,’x.y.z’) 方法,可以判断 o.x.y.z 路径是否存在对应属性</p><p>const o = {x:{y:{z:0}}}</p><p>hasProperty(o,’x.y.z’) // true</p><p>hasProperty(o,’x.w’) // false</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">hasProperty</span> <span class="token punctuation">(</span><span class="token parameter">o<span class="token punctuation">,</span> k</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>o <span class="token operator">===</span> <span class="token keyword">null</span> <span class="token operator">||</span> <span class="token keyword">typeof</span> o <span class="token operator">!==</span> <span class="token string">'object'</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">let</span> a <span class="token operator">=</span> k<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">'.'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">while</span><span class="token punctuation">(</span>i <span class="token operator"><</span> a<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>a<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token keyword">in</span> o<span class="token punctuation">)</span> <span class="token punctuation">{</span> o <span class="token operator">=</span> o<span class="token punctuation">[</span>a<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span> i<span class="token operator">++</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">false</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">const</span> o <span class="token operator">=</span> <span class="token punctuation">{</span>x<span class="token operator">:</span><span class="token punctuation">{</span>y<span class="token operator">:</span><span class="token punctuation">{</span>z<span class="token operator">:</span><span class="token number">0</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">}</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">hasProperty</span><span class="token punctuation">(</span>o<span class="token punctuation">,</span><span class="token string">'x.w'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>2.给定任意二维数组,输出所有的顺序排列组合项。</p><p>比如 [[‘A’,’B’], [‘a’,’b’], [1, 2]],输出 [‘Aa1’,’Aa2’,’Ab1’,’Ab2’,’Ba1’,’Ba2’,’Bb1’,’Bb2’]</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">combine</span> <span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">for</span>(<span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span>)<span class="token punctuation">{</span> <span class="token keyword">let</span> k <span class="token operator">=</span> arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator"><</span> k<span class="token punctuation">.</span>length<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> a<span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>3.给定数组 [‘1a’,’2b’,’13c’,’5a’] ,输出出现次数最多的字母前数字之和 6。</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">sum</span> <span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> m <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> q <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> k <span class="token operator">=</span> arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> n <span class="token operator">=</span> <span class="token operator">+</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>k <span class="token keyword">in</span> m<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> c <span class="token operator">=</span> m<span class="token punctuation">[</span>k<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> d <span class="token operator">=</span> q<span class="token punctuation">[</span>k<span class="token punctuation">]</span><span class="token punctuation">;</span> m<span class="token punctuation">[</span>k<span class="token punctuation">]</span> <span class="token operator">=</span> c<span class="token operator">++</span><span class="token punctuation">;</span> q<span class="token punctuation">[</span>k<span class="token punctuation">]</span> <span class="token operator">=</span> d <span class="token operator">+</span> n<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> m<span class="token punctuation">[</span>k<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> q<span class="token punctuation">[</span>k<span class="token punctuation">]</span> <span class="token operator">=</span> n<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> max <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">let</span> maxKey<span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> key <span class="token keyword">in</span> m<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">let</span> val <span class="token operator">=</span> m<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>val <span class="token operator">></span> max<span class="token punctuation">)</span> <span class="token punctuation">{</span> maxKey <span class="token operator">=</span> key<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> q<span class="token punctuation">[</span>maxKey<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'1a'</span><span class="token punctuation">,</span><span class="token string">'2b'</span><span class="token punctuation">,</span><span class="token string">'13c'</span><span class="token punctuation">,</span><span class="token string">'5a'</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token function">sum</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>4.Promise.resolve().then(()=>{</p><p>return new Promise(res => res(new Promise(res => res(123))))</p><p>})</p><p>.then( data => console.log(data))</p><p>5.vue里面 data () {</p><p> return {</p><p> a: [1, {b: 2 }, 3]</p><p> }</p><p>}</p><p>a[0]= 4; </p><p>a[1].b = 5;</p><p>a.push(6);</p><p>watch 监听情况</p><p>6.箭头函数和普通函数的区别</p><p>7.304 状态码意思 服务端什么时候会返回304</p><p>8.js 外链脚本是否一定会执行</p><h3 id="新浪"><a href="#新浪" class="headerlink" title="新浪"></a>新浪</h3><h4 id="一面-1"><a href="#一面-1" class="headerlink" title="一面"></a>一面</h4><p>1.手写instanceof</p><p>2.数据类型有哪些以及怎么判断</p><p>3.ES6有哪些新特性,列举一下</p><p>4.sleep</p><p>5.手机号中间四位替换成****</p><p>6.flat实现</p><p>7.闭包是怎么导致的</p><p>8.继承及各自优缺点</p><p>9文件分片上传,断点续传,秒传(简历写的),安全问题</p><p>10.对职位的期待</p><p>11.怎么培养新人及增强团队凝聚力</p><p>12.团队没有项目做的时候怎么办</p><p>比较基础</p>]]></content>
<categories>
<category> 面试 </category>
</categories>
<tags>
<tag> 面试 </tag>
</tags>
</entry>
<entry>
<title>进大厂,你准备好了吗</title>
<link href="2021/05/06/frontend/jin-da-han-ni-zhun-bei-hao-liao-ma/"/>
<url>2021/05/06/frontend/jin-da-han-ni-zhun-bei-hao-liao-ma/</url>
<content type="html"><![CDATA[<p>每个人都想进大厂,下面根据我的复习方法,希望能给你一些参考</p><h3 id="简历准备"><a href="#简历准备" class="headerlink" title="简历准备"></a>简历准备</h3><p>可以先写一个</p><h3 id="知识点准备"><a href="#知识点准备" class="headerlink" title="知识点准备"></a>知识点准备</h3><h3 id="项目准备"><a href="#项目准备" class="headerlink" title="项目准备"></a>项目准备</h3><h3 id="面试准备"><a href="#面试准备" class="headerlink" title="面试准备"></a>面试准备</h3><p>刷题</p><p>自我介绍等</p>]]></content>
<categories>
<category> 前端 </category>
<category> 面试 </category>
</categories>
<tags>
<tag> CSS </tag>
<tag> JavaScript </tag>
<tag> HTML </tag>
</tags>
</entry>
<entry>
<title>关于面试</title>
<link href="2021/05/06/frontend/guan-yu-mian-shi/"/>
<url>2021/05/06/frontend/guan-yu-mian-shi/</url>
<content type="html"><![CDATA[<p>面试的时候,心态要摆正,每一次面试当作是和面试官的一次技术交流,从面试中发现自己的不足,以便过后再去弥补。把自己知道最大的最大限度的展示出来,不知道的,虚心的请教和探讨。</p>]]></content>
<categories>
<category> 面试 </category>
</categories>
<tags>
<tag> 面试 </tag>
</tags>
</entry>
<entry>
<title>记录一次使用 yarn patch 遇到的问题</title>
<link href="2021/04/10/tool-instruction/ji-lu-yi-ci-shi-yong-yarn-patch-yu-dao-de-wen-ti-ti/"/>
<url>2021/04/10/tool-instruction/ji-lu-yi-ci-shi-yong-yarn-patch-yu-dao-de-wen-ti-ti/</url>
<content type="html"><![CDATA[<p>最近在修改 node_modules 里的文件时(具体可以参考我的另一篇文章—修改 node_modules 里文件的正确姿势),发现了 yarn patch 这个特性,这是 v2 版本的一个新特性,于是想动手实验一番,结果报了如下错误:</p><p><img src="/images/blog/modify-node_modules/screenshot12.jpg" alt="screenshot12"></p><p>意思是说在我的 lockfile 文件里面找不到我的这个依赖包,我一脸黑人问号, 明明刚安装了这个包,为什么会找不到呢?</p><p><img src="/images/blog/yarn-patch/confuse.jpg" alt="img"></p><p>于是我重新 <code>yarn install</code> 一下,发现了如下错误(用的是vue-cli4):</p><p><img src="/images/blog/yarn-patch/screenshot1.jpg" alt="screenshot1"></p><p>猜想会不会是因为 <a href="mailto:[email protected]">[email protected]</a> 这个包的镜像问题导致最后安装没有成功,然后去 npm 搜了一下这个包,发现没有这个版本的包依赖,又去工程项目里面搜了一下是哪个包依赖了 vue-loader-v16,发现了这个</p><p><img src="/images/blog/yarn-patch/screenshot2.jpg" alt="screenshot2"></p><p>“npm:” 是什么鬼,查了一下,发现这是一个别名,也就是说,安装 vue-loader-v16 的时候会去安装 vue-loader@^16.1.0,难道是 v2 版本的 yarn 安装的时候识别不出这种别名吗?因为我发现用 v1 版本的 yarn 安装的时候是没问题的。于是我立马试验了一番,另起一个工程,添加 一个包别名,是能安装成功的,证明 v2 版本的 yarn 识别这种别名是没有问题的。那到底是什么原因导致没有安装成功呢?</p><p>仔细看最开始的报错,注意到这段话, “try to make an install to update your resolutions”,查看 v1 版本的 yarn.lock 文件时,发现的是这样</p><p><img src="/images/blog/yarn-patch/screenshot3.jpg" alt="screenshot3"></p><p>安装包的地址应该是保存在 resolved 字段里面的,但是为什么这里的报错却提示是 resolutions 呢?难道 v2 版本的 yarn 换了字段名吗?于是我删掉了 yarn.lock 文件,重新 <code>yarn install</code> 一下,结果安装成功了,然后我查看了一下 v2 版本的 yarn.lock 文件</p><p><img src="/images/blog/yarn-patch/screenshot4.jpg" alt="screenshot4"></p><p>发现里面的字段名的确是 resolution ,由此证实了我的猜想。</p><p>所以最开始的安装没成功是因为 yarn 试图去找 resolution 对应的安装包地址,结果没有找到而报错。</p><p>由此得出结论:<strong>当把 yarn 升级到 v2 时,要先删除原来的 yarn.lock 文件,然后再执行 <code>yarn install</code>。</strong></p>]]></content>
<categories>
<category> 教程 </category>
</categories>
<tags>
<tag> Yarn </tag>
</tags>
</entry>
<entry>
<title>修改 node_modules 里文件的正确姿势</title>
<link href="2021/04/06/frontend/xiu-gai-node-modules-li-wen-jian-de-zheng-que-zi-shi/"/>
<url>2021/04/06/frontend/xiu-gai-node-modules-li-wen-jian-de-zheng-que-zi-shi/</url>
<content type="html"><![CDATA[<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>我们在开发的时候经常会遇到这种情况:</p><ol><li>所依赖的 npm 包有 bug,别人一时半会更新不了</li><li>不满足自己的需求(比如一些 UI 框架),需要修改某些部分</li></ol><p>那么这个时候我们就要去修改 node_modules 里面的源码,直接修改会导致两个问题:</p><p>第一,更新问题,重新安装之后,修改的文件会被覆盖</p><p>第二,同步问题,node_modules 里的文件一般是不提交到代码库的,那如何让团队其他成员也能同步更新呢?你总不能每次改完之后都手动发给其他人吧。</p><p>你可能首先想到的解决办法有这样两个:</p><ol><li>把别人代码全部复制到自己的 src 目录,修改完之后引入</li><li>把别人代码下载到本地,修改完之后重新发布为一个包,然后再安装自己发布的这个包</li></ol><p>但这两个解决办法都有上述提到的更新问题,当这个依赖包有更新时,没法自动同步更新。而且我们引入依赖包的时候,往往引入的是编译之后的代码,这样会导致每次修改完代码之后,还得自己手动编译,很麻烦,那有没有其他更好的解决办法呢?答案是肯定的。我想到的有这样几个解决办法,我们来逐一分析一下。</p><h3 id="说明"><a href="#说明" class="headerlink" title="说明"></a>说明</h3><p><strong>以下所有解决方案都以 request 包为例进行演示。</strong></p><h3 id="npm-link"><a href="#npm-link" class="headerlink" title="npm link"></a>npm link</h3><p>npm link 相当于建立一个软连接,将我们依赖的包链接到我们修改之后的包,这个在调试本地包的时候经常会用到,下面我们来实际操作一下。</p><ol><li>fork request 的仓库到自己的仓库,我这里命名为 request-study</li><li>clone 到本地</li><li>进入到 request-study 目录,执行 <code>npm link</code></li></ol><p><img src="/images/blog/modify-node_modules/screenshot1.jpg" alt="screenshot1"></p><ol start="4"><li><p>进入到我们的工程目录,执行 <code>npm link request</code></p><p><img src="/images/blog/modify-node_modules/screenshot2.jpg" alt="screenshot2"></p></li></ol><ol start="5"><li>修改包文件里面的代码,这里我们修改的目录是 request-study/lib/auth.js</li></ol><p><img src="/images/blog/modify-node_modules/screenshot3.png" alt="screenshot3"></p><p>这样当包里面的文件更新的时候会自动同步到工程项目里面,解决了上述更新的问题。不足的一个地方是当依赖包有更新时,团队其他成员也需要拉取最新的依赖包代码。</p><h3 id="webpack-alias"><a href="#webpack-alias" class="headerlink" title="webpack alias"></a>webpack alias</h3><p>webpack alias 的作用是配置别名,比如像这样:</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token function-variable function">chainWebpack</span><span class="token operator">:</span> <span class="token parameter">config</span> <span class="token operator">=></span> <span class="token punctuation">{</span> config<span class="token punctuation">.</span>resolve<span class="token punctuation">.</span>alias <span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'@'</span><span class="token punctuation">,</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token string">'./src'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'request/a'</span><span class="token punctuation">,</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token string">'./src/a'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>所以我们可以利用 webpack alias 将需要修改的文件代理到我们自己的项目文件中,操作步骤如下:</p><ol><li>找到别人源码里面的需要修改的文件,复制到 src 目录</li><li>修改代码,注意里面引用其他的文件路径都需要改成绝对路径</li><li>找到这个模块被引入的路径(<strong>我们需要拦截的路径</strong>)</li><li>配置 webpack alias</li></ol><p>我们来实际操作一下。</p><p>我们修改的文件如下:</p><p><img src="/images/blog/modify-node_modules/screenshot4.jpg" alt="screenshot4"></p><p>文件被引用的路径为 ./lib/auth (我们要拦截的路径) </p><p><img src="/images/blog/modify-node_modules/screenshot5.png" alt="screenshot5"></p><p>将 auth.js 文件复制到 src/assets/auth.js,将 require 路径中引入为当前request包的路径修改为绝对路径,并添加我们的代码</p><p><img src="/images/blog/modify-node_modules/screenshot6.jpg" alt="screenshot6"></p><p>配置 webpack alias (我这里用的是 vue-cli4, 配置文件是 vue.config.js),配置代码为</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> path <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'path'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function-variable function">chainWebpack</span><span class="token operator">:</span> <span class="token parameter">config</span> <span class="token operator">=></span> <span class="token punctuation">{</span> config<span class="token punctuation">.</span>resolve<span class="token punctuation">.</span>alias <span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'./lib/auth'</span><span class="token punctuation">,</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>__dirname<span class="token punctuation">,</span> <span class="token string">'src/assets/auth.js'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>启动我们的项目,控制台打印出我们添加的代码,表明我们的代码添加成功。</p><p><img src="/images/blog/modify-node_modules/screenshot7.jpg" alt="screenshot7"></p><p>当依赖包的代码有更新时,我们也能同步更新,团队其他成员同步修改的代码时也不需要做其它额外的操作。不足的一个地方是当我们修改的依赖包是在配置文件中(比如 vue.config.js)引入时,这个不会生效。</p><h3 id="yarn-patch"><a href="#yarn-patch" class="headerlink" title="yarn patch"></a>yarn patch</h3><p>这个需要用到 v2 版本的 yarn,具体步骤如下:</p><ol><li>全局安装 Yarn 的最新版本:<code>npm install -g yarn</code> ,这里说明一下,如果你之前安装的是应用程序版本,需要先卸载之后再运行这个命令,不然安装完成之后还是之前的 yarn 版本。</li><li>进入你的项目目录,运行 <code>yarn set version berry</code> 命令。</li></ol><p><img src="/images/blog/modify-node_modules/screenshot8.jpg" alt="screenshot8"></p><ol start="3"><li><p>执行 <code>yarn patch request</code> 命令</p><p><img src="/images/blog/modify-node_modules/screenshot9.jpg" alt="screenshot9"></p></li></ol><ol start="4"><li><p>在如上图所示文件路径中修改代码</p></li><li><p>在你的项目根目录新建一个 patches 文件夹,执行 <code>yarn patch-commit C:\Users\TWITTY~1\AppData\Local\Temp\xfs-f6241b39 > E:\vue-cli4\patches\request+2.88.2.patch</code>,这样你就能在 patches 文件下看到生成了一个 request+2.88.2.patch 文件,里面保存有你刚才修改代码的 diff 内容。</p></li><li><p>修改package.json 文件如下:</p><pre class="line-numbers language-json" data-language="json"><code class="language-json">- <span class="token property">"request"</span><span class="token operator">:</span> <span class="token string">"^2.88.2"</span> + <span class="token property">"request"</span><span class="token operator">:</span> <span class="token string">"patch:request@^2.88.2#./patches/request+2.88.2.patch"</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li><li><p>重新运行 yarn 和 启动项目,你就能看到依赖包代码修改之后的变化</p><p><img src="/images/blog/modify-node_modules/screenshot10.jpg" alt="screenshot10"></p></li></ol><p>这种办法解决了上述更新和团队成员同步问题,缺点是操作起来比较繁琐,还得依赖 v2 版本的 yarn。</p><h3 id="yarn-patch-可能出现的问题:"><a href="#yarn-patch-可能出现的问题:" class="headerlink" title="yarn patch 可能出现的问题:"></a>yarn patch 可能出现的问题:</h3><ol><li><p>运行 <code>yarn set version berry</code> 时,如果出现类似以下这种错误</p><p><img src="/images/blog/modify-node_modules/screenshot11.jpg" alt="screenshot11"></p><p>则可能需要用代理,命令行配置代理方法如下:</p><p>windows: </p><pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token builtin class-name">set</span> <span class="token assign-left variable">http_proxy</span><span class="token operator">=</span>http://127.0.0.1:1080<span class="token builtin class-name">set</span> <span class="token assign-left variable">https_proxy</span><span class="token operator">=</span>http://127.0.0.1:1080<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>mac:</p><pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token builtin class-name">export</span> <span class="token assign-left variable">http_proxy</span><span class="token operator">=</span>http://127.0.0.1:1080<span class="token builtin class-name">export</span> <span class="token assign-left variable">https_proxy</span><span class="token operator">=</span>http://127.0.0.1:1080<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li></ol><ol start="2"><li><p>运行 <code>yarn patch request</code> 命令时,如果出现以下这种情况,则需要删除 yarn.lock 文件,重新执行 <code>yarn install</code>。</p><p><img src="/images/blog/modify-node_modules/screenshot12.jpg" alt="screenshot12"></p><p>具体可以参考我的另一篇文章—记录一次使用 yarn patch 遇到的问题。</p></li></ol><ol start="3"><li><p>运行 <code>yarn patch request</code> 命令时,如果出现以下这种情况,说明有多个版本的包共存,你可以选择你具体要修改的那个包版本,比如我想修改的是 request 的2.88.2 版本,就执行 <code>yarn patch request@npm:2.88.2</code>。</p><p><img src="/images/blog/modify-node_modules/screenshot13.jpg" alt="screenshot13"></p></li></ol><h3 id="patch-package"><a href="#patch-package" class="headerlink" title="patch-package"></a>patch-package</h3><p>操作步骤如下:</p><ol><li><p>修改package.json 文件如下:</p><pre class="line-numbers language-json" data-language="json"><code class="language-json"><span class="token property">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span>+ <span class="token property">"postinstall"</span><span class="token operator">:</span> <span class="token string">"patch-package"</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p>安装 patch-package: <code>npm i patch-package -S</code></p></li><li><p>在 node_modules 里面修改依赖包的代码</p></li><li><p>每次修改代码之后执行命令 <code>npx patch-package request</code> </p></li></ol><p>最终会在项目根目录生成一个 patches 文件夹,里面保存着修改过的文件记录。</p><p><img src="/images/blog/modify-node_modules/screenshot14.jpg" alt="screenshot14"></p><p>你可能已经看到了,这种解决办法和 yarn patch 很像。是的,patch-package 可以看作是 yarn patch 的简化版,它相当于封装了 yarn patch 繁琐的操作。</p><h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><p>我们总结一下四种方法:</p><p>npm link 团队其他成员更新时需要同时更新修改依赖包;</p><p>webpack alias 不适用配置文件依赖的包;</p><p>yarn patch 需要将 yarn 升级到 v2 版本,操作步骤多;</p><p>patch-package 可以看做是 yarn patch 的一种替代方案,简化了 yarn patch 的很多操作,是一个比较理想的解决方案。</p><h3 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h3><p>码字不易,如果觉得对你有点帮助的话,还请动动你可爱的小指,帮忙点个赞;</p><p>如果你还有其他解决办法或者问题,也欢迎留言交流。</p><p>参考资料: </p><p><a href="https://juejin.cn/post/6844904163558555662">https://juejin.cn/post/6844904163558555662</a></p><p><a href="https://yarnpkg.com/">https://yarnpkg.com</a></p>]]></content>
<categories>
<category> node </category>
</categories>
<tags>
<tag> Node </tag>
</tags>
</entry>
<entry>
<title>关于数组的一些操作</title>
<link href="2021/04/04/frontend/guan-yu-shu-zu-de-yi-xie-cao-zuo/"/>
<url>2021/04/04/frontend/guan-yu-shu-zu-de-yi-xie-cao-zuo/</url>
<content type="html"><![CDATA[<p>参考资料</p><p><a href="https://segmentfault.com/a/1190000018549643">https://segmentfault.com/a/1190000018549643</a></p><p><a href="https://juejin.cn/post/6844903856489365518#heading-23">https://juejin.cn/post/6844903856489365518#heading-23</a></p>]]></content>
<categories>
<category> 前端 </category>
</categories>
<tags>
<tag> JavaScript </tag>
</tags>
</entry>
<entry>
<title>JavaScript中神奇的写法</title>
<link href="2021/03/03/frontend/javascript-zhong-shen-qi-de-xie-fa/"/>
<url>2021/03/03/frontend/javascript-zhong-shen-qi-de-xie-fa/</url>
<content type="html"><![CDATA[<h3 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a>写在前面</h3><h3 id="提前声明"><a href="#提前声明" class="headerlink" title="提前声明"></a>提前声明</h3><p>本文只是给你提供一个视角,让你觉得‘噢,原来还可以这么写’,但实际业务中一般不会用到。</p><h4 id="1-连续调用-call,到底是为谁打-call"><a href="#1-连续调用-call,到底是为谁打-call" class="headerlink" title="1. 连续调用 call,到底是为谁打 call"></a>1. 连续调用 call,到底是为谁打 call</h4><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">f1</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'f1'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">f2</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'f2'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>f1<span class="token punctuation">.</span>call<span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>f2<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment">// f2</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>因为call本来也是一个函数,所以它也有call方法。前面不论调用多少个call,最终返回的都是call方法本身,最后传入f2参数之后相当于执行f2.call();</p><h4 id="2-try-中-return,finally-中还会执行吗"><a href="#2-try-中-return,finally-中还会执行吗" class="headerlink" title="2. try 中 return,finally 中还会执行吗"></a>2. try 中 return,finally 中还会执行吗</h4><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">foo</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token string">'try'</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">finally</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token string">'finally'</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 1</span><span class="token comment">// 3</span><span class="token comment">// finally</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>在我们通常的理解中,return之后相当于这个函数就退出了,后面的代码都不会执行。但是这里我们可以看到finally最后确实是执行了, 而且里面的return覆盖了try中的return。这背后的执行机制与 Completion Record有关,关于Completion Record,这里就不展开讲了,有兴趣的可以去了解一下。</p><h4 id="3-连续new"><a href="#3-连续new" class="headerlink" title="3. 连续new"></a>3. 连续new</h4><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">class</span> <span class="token class-name">Person</span> <span class="token punctuation">{</span> <span class="token function">constructor</span> <span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span><span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Person"</span><span class="token punctuation">,</span> n<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Person 1</span> <span class="token keyword">return</span> <span class="token keyword">class</span> <span class="token punctuation">{</span> <span class="token function">constructor</span> <span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"returned"</span><span class="token punctuation">,</span> n<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// returned undefined</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token keyword">new</span> <span class="token class-name">new</span> <span class="token function">Person</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>我们可以将 <strong>new new Person(1)</strong> 拆分成如下执行过程:</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> p <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">new</span> <span class="token class-name">p</span><span class="token punctuation">;</span> <span class="token comment">// 这里没有参数的时候括号是可以省略的</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>这里的p 相当于</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">class</span> <span class="token punctuation">{</span> <span class="token function">constructor</span> <span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"returned"</span><span class="token punctuation">,</span> n<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>现在应该理解了吧。</p><h3 id="写在后面"><a href="#写在后面" class="headerlink" title="写在后面"></a>写在后面</h3><p>如果觉得对你有点帮助的话,请为我打call。另外还有哪些让你惊呼还可以这么写的用法,欢迎补充。</p><p>参考: winter老师《重学前端》</p>]]></content>
<categories>
<category> 前端 </category>
</categories>
<tags>
<tag> JavaScript </tag>
</tags>
</entry>
<entry>
<title>这些常见的手写题,你掌握了吗</title>
<link href="2021/02/25/frontend/zhe-xie-chang-jian-de-shou-xie-ti-ni-zhang-wo-liao-ma/"/>
<url>2021/02/25/frontend/zhe-xie-chang-jian-de-shou-xie-ti-ni-zhang-wo-liao-ma/</url>
<content type="html"><![CDATA[<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>手写代码很能考验面试者的编码能力,所以这类题常常受到面试官的青睐,如果没提前准备的话,经常会有挂一漏万的情况,现在我们来总结一下那些经常被问到的手写题。</p><h3 id="1-实现-instanceof-运算符"><a href="#1-实现-instanceof-运算符" class="headerlink" title="1. 实现 instanceof 运算符"></a>1. 实现 instanceof 运算符</h3><p>instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上,运算符左侧是实例对象,右侧是构造函数。</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token function-variable function">iInstanceof</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">left<span class="token punctuation">,</span> right</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 如果是原始值,则始终返回 false</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>left <span class="token operator">===</span> <span class="token keyword">null</span> <span class="token operator">||</span> <span class="token keyword">typeof</span> left <span class="token operator">!==</span> <span class="token string">'object'</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span><span class="token keyword">let</span> proto <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">getPrototypeOf</span><span class="token punctuation">(</span>left<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>proto <span class="token operator">===</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>proto <span class="token operator">===</span> right<span class="token punctuation">.</span>prototype<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> proto <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">getPrototypeOf</span><span class="token punctuation">(</span>proto<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>这是常见的实现,我们也可以用 isPrototypeOf 实现</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token function-variable function">iInstanceof</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">left<span class="token punctuation">,</span> right</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">return</span> right<span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function">isPrototypeOf</span><span class="token punctuation">(</span>left<span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><h3 id="2-实现-new-操作符"><a href="#2-实现-new-操作符" class="headerlink" title="2. 实现 new 操作符"></a>2. 实现 new 操作符</h3><p>new 执行过程如下:</p><ol><li><p>创建一个新对象;</p></li><li><p>新对象的[[prototype]]特性指向构造函数的prototype属性;</p></li><li><p>构造函数内部的this指向新对象;</p></li><li><p>执行构造函数;</p></li><li><p>如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象;</p></li></ol><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token function-variable function">iNew</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">fn<span class="token punctuation">,</span> <span class="token operator">...</span>rest</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">let</span> instance <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span>fn<span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> res <span class="token operator">=</span> <span class="token function">fn</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>instance<span class="token punctuation">,</span> rest<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> res <span class="token operator">!==</span> <span class="token keyword">null</span> <span class="token operator">&&</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> res <span class="token operator">===</span> <span class="token string">'object'</span> <span class="token operator">||</span> <span class="token keyword">typeof</span> res <span class="token operator">===</span> <span class="token string">'function'</span><span class="token punctuation">)</span> <span class="token operator">?</span> res <span class="token operator">:</span> instance<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="3-实现-Object-assign-方法"><a href="#3-实现-Object-assign-方法" class="headerlink" title="3. 实现 Object.assign 方法"></a>3. 实现 Object.assign 方法</h3><p>浅拷贝方法,只会拷贝源对象自身的且可枚举的属性(包括以 Symbol 为 key 的属性)到目标对象</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token function-variable function">iAssign</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">target<span class="token punctuation">,</span> <span class="token operator">...</span>source</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>target <span class="token operator">===</span> <span class="token keyword">null</span> <span class="token operator">||</span> target <span class="token operator">===</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">TypeError</span><span class="token punctuation">(</span><span class="token string">'Cannot convert undefined or null to object'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> res <span class="token operator">=</span> <span class="token function">Object</span><span class="token punctuation">(</span>target<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> source<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> src <span class="token operator">=</span> source<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> keys <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>src<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">...</span>Object<span class="token punctuation">.</span><span class="token function">getOwnPropertySymbols</span><span class="token punctuation">(</span>src<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> k <span class="token keyword">of</span> keys<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>src<span class="token punctuation">.</span><span class="token function">propertyIsEnumerable</span><span class="token punctuation">(</span>k<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> res<span class="token punctuation">[</span>k<span class="token punctuation">]</span> <span class="token operator">=</span> src<span class="token punctuation">[</span>k<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> res<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">// 保持 assign 的数据属性一致</span>Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> <span class="token string">'iAssign'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> value<span class="token operator">:</span> iAssign<span class="token punctuation">,</span> configurable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> enumerable<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> writable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="4-bind-方法"><a href="#4-bind-方法" class="headerlink" title="4. bind 方法"></a>4. bind 方法</h3><p>改变函数内 this 的值并且传参,返回一个函数</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token function-variable function">iBind</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">thisArg<span class="token punctuation">,</span> <span class="token operator">...</span>args</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> originFunc <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">boundFunc</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 解决 bind 之后对返回函数 new 的问题</span> <span class="token keyword">return</span> <span class="token function">originFunc</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword">new</span><span class="token punctuation">.</span>target <span class="token operator">?</span> <span class="token keyword">this</span> <span class="token operator">:</span> thisArg<span class="token punctuation">,</span> args<span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span>args1<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>originFunc<span class="token punctuation">.</span>prototype<span class="token punctuation">)</span> <span class="token punctuation">{</span> boundFunc<span class="token punctuation">.</span>prototype <span class="token operator">=</span> originFunc<span class="token punctuation">.</span>prototype<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 解决length 和 name 属性问题</span> <span class="token keyword">const</span> desc <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">getOwnPropertyDescriptors</span><span class="token punctuation">(</span>originFunc<span class="token punctuation">)</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">defineProperties</span><span class="token punctuation">(</span>boundFunc<span class="token punctuation">,</span> <span class="token punctuation">{</span> length<span class="token operator">:</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span>desc<span class="token punctuation">.</span>length<span class="token punctuation">,</span> <span class="token punctuation">{</span> value<span class="token operator">:</span> desc<span class="token punctuation">.</span>length<span class="token punctuation">.</span>value <span class="token operator"><</span> args<span class="token punctuation">.</span>length <span class="token operator">?</span> <span class="token number">0</span> <span class="token operator">:</span> <span class="token punctuation">(</span>desc<span class="token punctuation">.</span>length<span class="token punctuation">.</span>value <span class="token operator">-</span> args<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span> name<span class="token operator">:</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span>desc<span class="token punctuation">.</span>name<span class="token punctuation">,</span> <span class="token punctuation">{</span> value<span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">bound </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>desc<span class="token punctuation">.</span>name<span class="token punctuation">.</span>value<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> boundFunc<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">// 保持 bind 的数据属性一致</span>Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span><span class="token class-name">Function</span><span class="token punctuation">.</span>prototype<span class="token punctuation">,</span> <span class="token string">'iBind'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> value<span class="token operator">:</span> iBind<span class="token punctuation">,</span> enumerable<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> configurable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> writable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="5-call-方法"><a href="#5-call-方法" class="headerlink" title="5. call 方法"></a>5. call 方法</h3><p>用指定的 this 值和参数来调用函数</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token function-variable function">iCall</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">thisArg<span class="token punctuation">,</span> <span class="token operator">...</span>args</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> thisArg <span class="token operator">=</span> <span class="token punctuation">(</span>thisArg <span class="token operator">===</span> <span class="token keyword">undefined</span> <span class="token operator">||</span> thisArg <span class="token operator">===</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token operator">?</span> window <span class="token operator">:</span> <span class="token function">Object</span><span class="token punctuation">(</span>thisArg<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> fn <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">'fn'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> thisArg<span class="token punctuation">[</span>fn<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span> <span class="token keyword">let</span> res <span class="token operator">=</span> thisArg<span class="token punctuation">[</span>fn<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">delete</span> thisArg<span class="token punctuation">[</span>fn<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">return</span> res<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">// 保持 call 的数据属性一致</span>Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span><span class="token class-name">Function</span><span class="token punctuation">.</span>prototype<span class="token punctuation">,</span> <span class="token string">'iCall'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> value<span class="token operator">:</span> iCall<span class="token punctuation">,</span> configurable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> enumerable<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> writable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="6-函数柯里化"><a href="#6-函数柯里化" class="headerlink" title="6. 函数柯里化"></a>6. 函数柯里化</h3><p>将一个多参数函数转化为多个嵌套的单参数函数。</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token function-variable function">curry</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">targetFn</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token function">fn</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>rest</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>targetFn<span class="token punctuation">.</span>length <span class="token operator">===</span> rest<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">targetFn</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> rest<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">fn</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token operator">...</span>rest<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">// 用法</span><span class="token keyword">function</span> <span class="token function">add</span> <span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> c<span class="token punctuation">,</span> d</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">+</span> b <span class="token operator">+</span> c <span class="token operator">+</span> d<span class="token punctuation">;</span><span class="token punctuation">}</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'柯里化:'</span><span class="token punctuation">,</span> <span class="token function">curry</span><span class="token punctuation">(</span>add<span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 柯里化: 10</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="7-函数防抖-debounce-方法"><a href="#7-函数防抖-debounce-方法" class="headerlink" title="7. 函数防抖 debounce 方法"></a>7. 函数防抖 debounce 方法</h3><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token function-variable function">debounce</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">func<span class="token punctuation">,</span> wait <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> options <span class="token operator">=</span> <span class="token punctuation">{</span> leading<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> context<span class="token operator">:</span> <span class="token keyword">null</span><span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> timer<span class="token punctuation">;</span> <span class="token keyword">let</span> res<span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">_debounce</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> options<span class="token punctuation">.</span>context <span class="token operator">||</span> <span class="token punctuation">(</span>options<span class="token punctuation">.</span>context <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>timer<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">clearTimeout</span><span class="token punctuation">(</span>timer<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>options<span class="token punctuation">.</span>leading <span class="token operator">&&</span> <span class="token operator">!</span>timer<span class="token punctuation">)</span> <span class="token punctuation">{</span> timer <span class="token operator">=</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> timer <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> wait<span class="token punctuation">)</span><span class="token punctuation">;</span> res <span class="token operator">=</span> <span class="token function">func</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>options<span class="token punctuation">.</span>context<span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> timer <span class="token operator">=</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> res <span class="token operator">=</span> <span class="token function">func</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>options<span class="token punctuation">.</span>context<span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span> timer <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> wait<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> res<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> _debounce<span class="token punctuation">.</span><span class="token function-variable function">cancel</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">clearTimeout</span><span class="token punctuation">(</span>timer<span class="token punctuation">)</span><span class="token punctuation">;</span> timer <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">return</span> _debounce<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>leading 表示进入时是否立即执行,如果在wait 时间内触发事件,则会将上一个定时器清除,并重新再设置一个 wait 时间的定时器。</p><h3 id="8-函数节流-throttle-方法"><a href="#8-函数节流-throttle-方法" class="headerlink" title="8. 函数节流 throttle 方法"></a>8. 函数节流 throttle 方法</h3><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token function-variable function">throttle</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">func<span class="token punctuation">,</span> wait <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> options <span class="token operator">=</span> <span class="token punctuation">{</span> leading<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> trailing<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> context<span class="token operator">:</span> <span class="token keyword">null</span><span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> timer<span class="token punctuation">;</span> <span class="token keyword">let</span> res<span class="token punctuation">;</span> <span class="token keyword">let</span> previous <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">_throttle</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> options<span class="token punctuation">.</span>context <span class="token operator">||</span> <span class="token punctuation">(</span>options<span class="token punctuation">.</span>context <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> now <span class="token operator">=</span> Date<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>previous <span class="token operator">&&</span> <span class="token operator">!</span>options<span class="token punctuation">.</span>leading<span class="token punctuation">)</span> previous <span class="token operator">=</span> now<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>now <span class="token operator">-</span> previous <span class="token operator">>=</span> wait<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>timer<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">clearTimeout</span><span class="token punctuation">(</span>timer<span class="token punctuation">)</span><span class="token punctuation">;</span> timer <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> res <span class="token operator">=</span> <span class="token function">func</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>options<span class="token punctuation">.</span>context<span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span> previous <span class="token operator">=</span> now<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>timer <span class="token operator">&&</span> options<span class="token punctuation">.</span>trailing<span class="token punctuation">)</span> <span class="token punctuation">{</span> timer <span class="token operator">=</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> res <span class="token operator">=</span> <span class="token function">func</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>options<span class="token punctuation">.</span>context<span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span> previous <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> timer <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> wait<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> res<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> _throttle<span class="token punctuation">.</span><span class="token function-variable function">cancel</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> previous <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token function">clearTimeout</span><span class="token punctuation">(</span>timer<span class="token punctuation">)</span><span class="token punctuation">;</span> timer <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">return</span> _throttle<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>函数节流就像水龙头滴水一样,间隔 wait 时间就会触发一次,这里相比函数防抖新增了 trailing 选项,表示是否在最后额外触发一次。</p><h3 id="9-事件发布订阅(EventBus-事件总线)"><a href="#9-事件发布订阅(EventBus-事件总线)" class="headerlink" title="9. 事件发布订阅(EventBus 事件总线)"></a>9. 事件发布订阅(EventBus 事件总线)</h3><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">class</span> <span class="token class-name">EventBus</span> <span class="token punctuation">{</span> <span class="token function">constructor</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token string">'handles'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> value<span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">on</span> <span class="token punctuation">(</span><span class="token parameter">eventName<span class="token punctuation">,</span> listener</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> listener <span class="token operator">!==</span> <span class="token string">'function'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span><span class="token string">'请传入正确的回调函数'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>handles<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>handles<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">this</span><span class="token punctuation">.</span>handles<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>listener<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">emit</span> <span class="token punctuation">(</span><span class="token parameter">eventName<span class="token punctuation">,</span> <span class="token operator">...</span>args</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> listeners <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>handles<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>listeners<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">warn</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>eventName<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">事件不存在</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> listener <span class="token keyword">of</span> listeners<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">listener</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">off</span> <span class="token punctuation">(</span><span class="token parameter">eventName<span class="token punctuation">,</span> listener</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>listener<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">delete</span> <span class="token keyword">this</span><span class="token punctuation">.</span>handles<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> listeners <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>handles<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>listeners <span class="token operator">&&</span> listeners<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> index <span class="token operator">=</span> listeners<span class="token punctuation">.</span><span class="token function">findIndex</span><span class="token punctuation">(</span><span class="token parameter">item</span> <span class="token operator">=></span> item <span class="token operator">===</span> listener<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">~</span>index<span class="token punctuation">)</span> <span class="token punctuation">{</span> listeners<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span>index<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">once</span> <span class="token punctuation">(</span><span class="token parameter">eventName<span class="token punctuation">,</span> listener</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> listener <span class="token operator">!==</span> <span class="token string">'function'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span><span class="token string">'请传入正确的回调函数'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> <span class="token function-variable function">onceListener</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">listener</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">off</span><span class="token punctuation">(</span>eventName<span class="token punctuation">,</span> onceListener<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span>eventName<span class="token punctuation">,</span> onceListener<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>自定义事件的时候用到,注意一些边界的检查</p><h3 id="10-深拷贝"><a href="#10-深拷贝" class="headerlink" title="10. 深拷贝"></a>10. 深拷贝</h3><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token function-variable function">deepClone</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">source</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>source <span class="token operator">===</span> <span class="token keyword">null</span> <span class="token operator">||</span> <span class="token keyword">typeof</span> source <span class="token operator">!==</span> <span class="token string">'object'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> source<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> res <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>source<span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> key <span class="token keyword">in</span> source<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name">Object</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function">hasOwnProperty</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>source<span class="token punctuation">,</span> key<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> res<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">deepClone</span><span class="token punctuation">(</span>source<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> res<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>这个是深拷贝的很基础版本,其中存在一些问题,比如循环引用,比如递归爆栈,后面我会专门写一篇文章来展开讨论。</p><h3 id="11-实现-ES6-的Class"><a href="#11-实现-ES6-的Class" class="headerlink" title="11. 实现 ES6 的Class"></a>11. 实现 ES6 的Class</h3><p>用构造函数模拟,class 只能用 new 创建,不可以直接调用,另外注意一下属性的描述符</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token function-variable function">checkNew</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">instance<span class="token punctuation">,</span> con</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>instance <span class="token keyword">instanceof</span> <span class="token class-name">con</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">TypeError</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Class constructor </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>con<span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> cannot be invoked without 'new'</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token keyword">const</span> <span class="token function-variable function">defineProperties</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">target<span class="token punctuation">,</span> obj</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> key <span class="token keyword">in</span> obj<span class="token punctuation">)</span> <span class="token punctuation">{</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> key<span class="token punctuation">,</span> <span class="token punctuation">{</span> configurable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> enumerable<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> value<span class="token operator">:</span> obj<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">,</span> writable<span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token keyword">const</span> <span class="token function-variable function">createClass</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">con<span class="token punctuation">,</span> proto<span class="token punctuation">,</span> staticAttr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> proto <span class="token operator">&&</span> <span class="token function">defineProperties</span><span class="token punctuation">(</span>con<span class="token punctuation">.</span>prototype<span class="token punctuation">,</span> proto<span class="token punctuation">)</span><span class="token punctuation">;</span> staticAttr <span class="token operator">&&</span> <span class="token function">defineProperties</span><span class="token punctuation">(</span>con<span class="token punctuation">,</span> staticAttr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> con<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">// 用法</span><span class="token keyword">function</span> <span class="token function">Person</span> <span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">checkNew</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> Person<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">var</span> PersonClass <span class="token operator">=</span> <span class="token function">createClass</span><span class="token punctuation">(</span>Person<span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token function-variable function">getName</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token function-variable function">getAge</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="12-实现-ES6-的继承"><a href="#12-实现-ES6-的继承" class="headerlink" title="12. 实现 ES6 的继承"></a>12. 实现 ES6 的继承</h3><p>ES6 内部使用寄生组合式继承,首先用 Object.create 继承原型,并传递第二个参数以将父类构造函数指向自身,同时设置数据属性描述符。</p><p>然后用 Object.setPrototypeOf 继承静态属性和静态方法。</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token function-variable function">inherit</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">subType<span class="token punctuation">,</span> superType</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 对 superType 进行类型判断</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> superType <span class="token operator">!==</span> <span class="token string">"function"</span> <span class="token operator">&&</span> superType <span class="token operator">!==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">TypeError</span><span class="token punctuation">(</span><span class="token string">"Super expression must either be null or a function"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> subType<span class="token punctuation">.</span>prototype <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span>superType <span class="token operator">&&</span> superType<span class="token punctuation">.</span>prototype<span class="token punctuation">,</span> <span class="token punctuation">{</span> constructor<span class="token operator">:</span> <span class="token punctuation">{</span> configurable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> enumerable<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> value<span class="token operator">:</span> subType<span class="token punctuation">,</span> writable<span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 继承静态方法</span>superType <span class="token operator">&&</span> Object<span class="token punctuation">.</span><span class="token function">setPrototypeOf</span><span class="token punctuation">(</span>subType<span class="token punctuation">,</span> superType<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">// 用法</span><span class="token keyword">function</span> <span class="token function">superType</span> <span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span><span class="token punctuation">}</span>superType<span class="token punctuation">.</span><span class="token function-variable function">staticFn</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'staticFn'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span>superType<span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">getName</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'name: '</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">subType</span> <span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> age</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">superType</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">inherit</span><span class="token punctuation">(</span>subType<span class="token punctuation">,</span> superType<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 必须在继承之后再往 subType 中添加原型方法,否则会被覆盖掉</span>subType<span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">getAge</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'age: '</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">let</span> subTypeInstance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">subType</span><span class="token punctuation">(</span><span class="token string">'Twittytop'</span><span class="token punctuation">,</span> <span class="token number">29</span><span class="token punctuation">)</span><span class="token punctuation">;</span>subType<span class="token punctuation">.</span><span class="token function">staticFn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>subTypeInstance<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>subTypeInstance<span class="token punctuation">.</span><span class="token function">getAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="13-图片懒加载"><a href="#13-图片懒加载" class="headerlink" title="13. 图片懒加载"></a>13. 图片懒加载</h3><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 获取窗口高度</span><span class="token keyword">function</span> <span class="token function">getWindowHeight</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> window<span class="token punctuation">.</span>innerHeight <span class="token operator">||</span> document<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>clientHeight <span class="token operator">||</span> document<span class="token punctuation">.</span>body<span class="token punctuation">.</span>clientHeight<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">getTop</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> t <span class="token operator">=</span> e<span class="token punctuation">.</span>offsetTop<span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>e <span class="token operator">=</span> e<span class="token punctuation">.</span>offsetParent<span class="token punctuation">)</span> <span class="token punctuation">{</span> t <span class="token operator">+=</span> e<span class="token punctuation">.</span>offsetTop<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> t<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">const</span> delta <span class="token operator">=</span> <span class="token number">30</span><span class="token punctuation">;</span><span class="token keyword">let</span> count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token keyword">function</span> <span class="token function">lazyLoad</span> <span class="token punctuation">(</span><span class="token parameter">imgs</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> winH <span class="token operator">=</span> <span class="token function">getWindowHeight</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> s <span class="token operator">=</span> document<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>scrollTop <span class="token operator">||</span> document<span class="token punctuation">.</span>body<span class="token punctuation">.</span>scrollTop<span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> l <span class="token operator">=</span> imgs<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i <span class="token operator"><</span> l<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>winH <span class="token operator">+</span> s <span class="token operator">+</span> delta <span class="token operator">></span> <span class="token function">getTop</span><span class="token punctuation">(</span>imgs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token function">getTop</span><span class="token punctuation">(</span>imgs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">+</span> imgs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>offsetHeight <span class="token operator">+</span> delta <span class="token operator">></span> s<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>imgs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>src<span class="token punctuation">)</span> <span class="token punctuation">{</span> imgs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>src <span class="token operator">=</span> imgs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">getAttribute</span><span class="token punctuation">(</span><span class="token string">'data-src'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> count<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>count <span class="token operator">===</span> l<span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">'scroll'</span><span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">'load'</span><span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token keyword">const</span> imgs <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">'img'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">const</span> <span class="token function-variable function">handler</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">lazyLoad</span><span class="token punctuation">(</span>imgs<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span>window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'scroll'</span><span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span>window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'load'</span><span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>当然你也可以用 getBoundingClientRect 方法:</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 获取窗口高度</span><span class="token keyword">function</span> <span class="token function">getWindowHeight</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> window<span class="token punctuation">.</span>innerHeight <span class="token operator">||</span> document<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>clientHeight <span class="token operator">||</span> document<span class="token punctuation">.</span>body<span class="token punctuation">.</span>clientHeight<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">const</span> delta <span class="token operator">=</span> <span class="token number">30</span><span class="token punctuation">;</span><span class="token keyword">let</span> count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token keyword">function</span> <span class="token function">lazyLoad</span> <span class="token punctuation">(</span><span class="token parameter">imgs</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> winH <span class="token operator">=</span> <span class="token function">getWindowHeight</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> l <span class="token operator">=</span> imgs<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i <span class="token operator"><</span> l<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> rect <span class="token operator">=</span> imgs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">getBoundingClientRect</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>winH <span class="token operator">+</span> delta <span class="token operator">></span> rect<span class="token punctuation">.</span>top <span class="token operator">&&</span> rect<span class="token punctuation">.</span>bottom <span class="token operator">></span> <span class="token operator">-</span>delta<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>imgs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>src<span class="token punctuation">)</span> <span class="token punctuation">{</span> imgs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>src <span class="token operator">=</span> imgs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">getAttribute</span><span class="token punctuation">(</span><span class="token string">'data-src'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> count<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>count <span class="token operator">===</span> l<span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">'scroll'</span><span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">'load'</span><span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token keyword">const</span> imgs <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">'img'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">const</span> <span class="token function-variable function">handler</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">lazyLoad</span><span class="token punctuation">(</span>imgs<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span>window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'scroll'</span><span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span>window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'load'</span><span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>当然你也可以用 IntersectionObserver 方法:</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">lazyLoad</span> <span class="token punctuation">(</span><span class="token parameter">imgs</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> options <span class="token operator">=</span> <span class="token punctuation">{</span> rootMargin<span class="token operator">:</span> <span class="token string">'30px'</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">let</span> observer <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">IntersectionObserver</span><span class="token punctuation">(</span><span class="token parameter">entries</span> <span class="token operator">=></span> <span class="token punctuation">{</span> entries<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token parameter">entry</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>entry<span class="token punctuation">.</span>intersectionRatio <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> entry<span class="token punctuation">.</span>target<span class="token punctuation">.</span>src <span class="token operator">=</span> entry<span class="token punctuation">.</span>target<span class="token punctuation">.</span><span class="token function">getAttribute</span><span class="token punctuation">(</span><span class="token string">'data-src'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> count<span class="token operator">++</span><span class="token punctuation">;</span> observer<span class="token punctuation">.</span><span class="token function">unobserve</span><span class="token punctuation">(</span>entry<span class="token punctuation">.</span>target<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>count <span class="token operator">===</span> imgs<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">'load'</span><span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> options<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> imgs<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> observer<span class="token punctuation">.</span><span class="token function">observe</span><span class="token punctuation">(</span>imgs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token keyword">const</span> imgs <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">'img'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">const</span> <span class="token function-variable function">handler</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">lazyLoad</span><span class="token punctuation">(</span>imgs<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span>window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'load'</span><span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="14-实现Object-is-方法"><a href="#14-实现Object-is-方法" class="headerlink" title="14. 实现Object.is 方法"></a>14. 实现Object.is 方法</h3><p>Object.is() 和 === 的区别是 Object.is(0, -0) 返回 false, Object.is(NaN, NaN) 返回 true。</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token function-variable function">iIs</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">===</span> y<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> x <span class="token operator">!==</span> <span class="token number">0</span> <span class="token operator">||</span> <span class="token number">1</span> <span class="token operator">/</span> x <span class="token operator">===</span> <span class="token number">1</span> <span class="token operator">/</span> y<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> x <span class="token operator">!==</span> x <span class="token operator">&&</span> y <span class="token operator">!==</span> y<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment">// 保持 is 的数据属性一致</span>Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span><span class="token class-name">Function</span><span class="token punctuation">.</span>prototype<span class="token punctuation">,</span> <span class="token string">'iIs'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> value<span class="token operator">:</span> iIs<span class="token punctuation">,</span> configurable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> enumerable<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> writable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="15-时间切片"><a href="#15-时间切片" class="headerlink" title="15. 时间切片"></a>15. 时间切片</h3><p>把长任务切割成多个小任务,使用场景是防止一个任务执行时间过长而阻塞线程</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">ts</span> <span class="token punctuation">(</span><span class="token parameter">gen</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> gen <span class="token operator">===</span> <span class="token string">'function'</span><span class="token punctuation">)</span> gen <span class="token operator">=</span> <span class="token function">gen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>gen <span class="token operator">||</span> <span class="token keyword">typeof</span> gen<span class="token punctuation">.</span>next <span class="token operator">!==</span> <span class="token string">'function'</span><span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> start <span class="token operator">=</span> performance<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> res <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token keyword">do</span> <span class="token punctuation">{</span> res <span class="token operator">=</span> gen<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">while</span><span class="token punctuation">(</span><span class="token operator">!</span>res<span class="token punctuation">.</span>done <span class="token operator">&&</span> performance<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> start <span class="token operator"><</span> <span class="token number">25</span><span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>res<span class="token punctuation">.</span>done<span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>next<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">// 用法</span><span class="token function">ts</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token operator">*</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> start <span class="token operator">=</span> performance<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>performance<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> start <span class="token operator"><</span> <span class="token number">1000</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">yield</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'done!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="16-CO-(协程)实现"><a href="#16-CO-(协程)实现" class="headerlink" title="16. CO (协程)实现"></a>16. CO (协程)实现</h3><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">co</span> <span class="token punctuation">(</span><span class="token parameter">gen</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> gen <span class="token operator">===</span> <span class="token string">'function'</span><span class="token punctuation">)</span> gen <span class="token operator">=</span> <span class="token function">gen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>gen <span class="token operator">||</span> <span class="token keyword">typeof</span> gen<span class="token punctuation">.</span>next <span class="token operator">!==</span> <span class="token string">'function'</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token function">resolve</span><span class="token punctuation">(</span>gen<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">onFulfilled</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">onFulfilled</span> <span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> ret<span class="token punctuation">;</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> ret <span class="token operator">=</span> gen<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">reject</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">next</span><span class="token punctuation">(</span>ret<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">onRejected</span> <span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> ret<span class="token punctuation">;</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> ret <span class="token operator">=</span> gen<span class="token punctuation">.</span><span class="token function">throw</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">reject</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">next</span><span class="token punctuation">(</span>ret<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">next</span> <span class="token punctuation">(</span><span class="token parameter">ret</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>ret<span class="token punctuation">.</span>done<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token function">resolve</span><span class="token punctuation">(</span>ret<span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> val <span class="token operator">=</span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>ret<span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> val<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>onFulfilled<span class="token punctuation">,</span> onRejected<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">// 用法</span><span class="token function">co</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token operator">*</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> res1 <span class="token operator">=</span> <span class="token keyword">yield</span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> res2 <span class="token operator">=</span> <span class="token keyword">yield</span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> res3 <span class="token operator">=</span> <span class="token keyword">yield</span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> res1 <span class="token operator">+</span> res2 <span class="token operator">+</span> res3<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">value</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'add: '</span> <span class="token operator">+</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span>err<span class="token punctuation">.</span>stack<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>co 接受一个生成器函数,当遇到 yield 时就暂停执行,交出控制权,当其他程序执行完毕后,将结果返回并从中断的地方继续执行,如此往复,一直到所有的任务都执行完毕,最后返回一个 Promise 并将生成器函数的返回值作为 resolve 值。</p><p>我们将 * 换成 async,将 yield 换成 await 时,就和我们经常用的 async/await 是一样的,所以说 async/await 是生成器函数的语法糖。</p><h3 id="17-单例模式"><a href="#17-单例模式" class="headerlink" title="17. 单例模式"></a>17. 单例模式</h3><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token function-variable function">getSingleton</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">fn</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> instance<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> instance <span class="token operator">||</span> <span class="token punctuation">(</span>instance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token punctuation">(</span><span class="token function">fn</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token operator">...</span>arguments<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">// 用法</span><span class="token keyword">function</span> <span class="token function">Person</span> <span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">let</span> singleton <span class="token operator">=</span> <span class="token function">getSingleton</span><span class="token punctuation">(</span>Person<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> instance1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">singleton</span><span class="token punctuation">(</span><span class="token string">'Twittytop1'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> instance2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">singleton</span><span class="token punctuation">(</span><span class="token string">'Twittytop2'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>instance1 <span class="token operator">===</span> instance2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>当然你也可以用 ES6 的 Proxy 实现:</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token function-variable function">getSingleton</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">fn</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> instance<span class="token punctuation">;</span> <span class="token keyword">const</span> handler <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">construct</span> <span class="token punctuation">(</span><span class="token parameter">target<span class="token punctuation">,</span> argumentsList</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> instance <span class="token operator">||</span> <span class="token punctuation">(</span>instance <span class="token operator">=</span> Reflect<span class="token punctuation">.</span><span class="token function">construct</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> argumentsList<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Proxy</span><span class="token punctuation">(</span>fn<span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">// 用法</span><span class="token keyword">function</span> <span class="token function">Person</span> <span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">let</span> singleton <span class="token operator">=</span> <span class="token function">getSingleton</span><span class="token punctuation">(</span>Person<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> instance1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">singleton</span><span class="token punctuation">(</span><span class="token string">'Twittytop1'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> instance2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">singleton</span><span class="token punctuation">(</span><span class="token string">'Twittytop2'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>instance1 <span class="token operator">===</span> instance2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="18-Promise"><a href="#18-Promise" class="headerlink" title="18. Promise"></a>18. Promise</h3><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">isFunction</span> <span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">typeof</span> obj <span class="token operator">===</span> <span class="token string">'function'</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">isObject</span> <span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token operator">!</span><span class="token operator">!</span><span class="token punctuation">(</span>obj <span class="token operator">&&</span> <span class="token keyword">typeof</span> obj <span class="token operator">===</span> <span class="token string">'object'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">isPromise</span> <span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> obj <span class="token keyword">instanceof</span> <span class="token class-name">Promise</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">isThenable</span> <span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token function">isFunction</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token function">isObject</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token string">'then'</span> <span class="token keyword">in</span> obj<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">transition</span> <span class="token punctuation">(</span><span class="token parameter">promise<span class="token punctuation">,</span> state<span class="token punctuation">,</span> result</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 一旦变成非 pending 状态,就不可逆</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>promise<span class="token punctuation">.</span>state <span class="token operator">!==</span> <span class="token string">'pending'</span><span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span> promise<span class="token punctuation">.</span>state <span class="token operator">=</span> state<span class="token punctuation">;</span> promise<span class="token punctuation">.</span>result <span class="token operator">=</span> result<span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> promise<span class="token punctuation">.</span>callbacks<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token parameter">callback</span> <span class="token operator">=></span> <span class="token function">handleCallback</span><span class="token punctuation">(</span>callback<span class="token punctuation">,</span> state<span class="token punctuation">,</span> result<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">resolvePromise</span> <span class="token punctuation">(</span><span class="token parameter">promise<span class="token punctuation">,</span> result<span class="token punctuation">,</span> resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>promise <span class="token operator">===</span> result<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">TypeError</span><span class="token punctuation">(</span><span class="token string">'Chaining cycle detected for promise'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isPromise</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> result<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>resolve<span class="token punctuation">,</span> reject<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isThenable</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> then <span class="token operator">=</span> result<span class="token punctuation">.</span>then<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isFunction</span><span class="token punctuation">(</span>then<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token function">then</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>resolve<span class="token punctuation">,</span> reject<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">reject</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">resolve</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">handleCallback</span> <span class="token punctuation">(</span><span class="token parameter">callback<span class="token punctuation">,</span> state<span class="token punctuation">,</span> result</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> <span class="token punctuation">{</span> onFulfilled<span class="token punctuation">,</span> onRejected<span class="token punctuation">,</span> resolve<span class="token punctuation">,</span> reject <span class="token punctuation">}</span> <span class="token operator">=</span> callback<span class="token punctuation">;</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>state <span class="token operator">===</span> <span class="token string">'fulfilled'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">isFunction</span><span class="token punctuation">(</span>onFulfilled<span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token function">onFulfilled</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">resolve</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>state <span class="token operator">===</span> <span class="token string">'rejected'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">isFunction</span><span class="token punctuation">(</span>onRejected<span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token function">onRejected</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">reject</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">reject</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token keyword">class</span> <span class="token class-name">Promise</span> <span class="token punctuation">{</span> <span class="token function">constructor</span> <span class="token punctuation">(</span><span class="token parameter">executor</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">=</span> <span class="token string">'pending'</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>result <span class="token operator">=</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>callbacks <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token function-variable function">onFulfilled</span> <span class="token operator">=</span> <span class="token parameter">value</span> <span class="token operator">=></span> <span class="token function">transition</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token string">'fulfilled'</span><span class="token punctuation">,</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token function-variable function">onRejected</span> <span class="token operator">=</span> <span class="token parameter">reason</span> <span class="token operator">=></span> <span class="token function">transition</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token string">'rejected'</span><span class="token punctuation">,</span> reason<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 保证 resolve 或 reject 只有一次调用</span> <span class="token keyword">let</span> flag <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token function-variable function">resolve</span> <span class="token operator">=</span> <span class="token parameter">value</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>flag<span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span> flag <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token function">resolvePromise</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> value<span class="token punctuation">,</span> onFulfilled<span class="token punctuation">,</span> onRejected<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token function-variable function">reject</span> <span class="token operator">=</span> <span class="token parameter">reason</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>flag<span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span> flag <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token function">onRejected</span><span class="token punctuation">(</span>reason<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token function">executor</span><span class="token punctuation">(</span>resolve<span class="token punctuation">,</span> reject<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">reject</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">then</span> <span class="token punctuation">(</span><span class="token parameter">onFulfilled<span class="token punctuation">,</span> onRejected</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> callback <span class="token operator">=</span> <span class="token punctuation">{</span> onFulfilled<span class="token punctuation">,</span> onRejected<span class="token punctuation">,</span> resolve<span class="token punctuation">,</span> reject <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">===</span> <span class="token string">'pending'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>callbacks<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>callback<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">handleCallback</span><span class="token punctuation">(</span>callback<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>onRejected<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">,</span> onRejected<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 无论成功还是失败都会执行,一般都会传递前一个 promise 的状态,只有在 onFinally 抛出错误(显示抛出或 reject)的时候才会返回一个 rejected 的 promise</span> <span class="token keyword">finally</span> <span class="token punctuation">(</span>onFinally<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span> <span class="token parameter">val</span> <span class="token operator">=></span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token function">onFinally</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> val<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token parameter">rea</span> <span class="token operator">=></span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token function">onFinally</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> rea<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> <span class="token function">resolve</span> <span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isPromise</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> value<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> <span class="token function">reject</span> <span class="token punctuation">(</span><span class="token parameter">reason</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">reject</span><span class="token punctuation">(</span>reason<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 当所有 promise 都返回 fulfilled 的时候,它才会返回一个 fulfilled 的 promise,里面包含了对应结果的数组,否则只要一个 promise 返回 rejected,它就会返回一个 rejected 的 promise,其中包含第一个 rejected 的 promise 抛出的错误信息</span> <span class="token keyword">static</span> <span class="token function">all</span> <span class="token punctuation">(</span><span class="token parameter">iterable</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> l <span class="token operator">=</span> iterable<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i <span class="token operator"><</span> l<span class="token punctuation">;</span> i <span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> iterable<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">val</span> <span class="token operator">=></span> <span class="token punctuation">{</span> count<span class="token operator">++</span><span class="token punctuation">;</span> arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> val<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>count <span class="token operator">===</span> l<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">reresolve</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> reject<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 只要有一个 promise 返回 fulfilled 或 rejected,它就会返回一个 fulfilled 或 rejected 的 promise</span> <span class="token keyword">static</span> <span class="token function">race</span> <span class="token punctuation">(</span><span class="token parameter">iterable</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> p <span class="token keyword">of</span> iterable<span class="token punctuation">)</span> <span class="token punctuation">{</span> p<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>resolve<span class="token punctuation">,</span> reject<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 当所有 promise 都 fulfilled 或 rejected 后,返回一个包含对应结果的数组</span> <span class="token keyword">static</span> <span class="token function">allSettled</span> <span class="token punctuation">(</span><span class="token parameter">iterable</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">handle</span> <span class="token punctuation">(</span><span class="token parameter">state<span class="token punctuation">,</span> index<span class="token punctuation">,</span> result</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> arr<span class="token punctuation">[</span>index<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">{</span> status<span class="token operator">:</span> state<span class="token punctuation">,</span> <span class="token punctuation">[</span>state <span class="token operator">===</span> <span class="token string">'fulfilled'</span> <span class="token operator">?</span> <span class="token string">'value'</span> <span class="token operator">:</span> <span class="token string">'reason'</span><span class="token punctuation">]</span><span class="token operator">:</span> result <span class="token punctuation">}</span><span class="token punctuation">;</span> count<span class="token operator">++</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>count <span class="token operator">===</span> iterable<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">resolve</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> l <span class="token operator">=</span> iterable<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i <span class="token operator"><</span> l<span class="token punctuation">;</span> i <span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> iterable<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">val</span> <span class="token operator">=></span> <span class="token function">handle</span> <span class="token punctuation">(</span><span class="token string">'fulfilled'</span><span class="token punctuation">,</span> i<span class="token punctuation">,</span> val<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token parameter">rea</span> <span class="token operator">=></span> <span class="token function">handle</span> <span class="token punctuation">(</span><span class="token string">'rejected'</span><span class="token punctuation">,</span> i<span class="token punctuation">,</span> rea<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 只要有一个 promise 成功,就会返回一个成功的 promise,否则返回一个 AggregateError 类型实例的失败 promise</span> <span class="token keyword">static</span> <span class="token function">any</span> <span class="token punctuation">(</span><span class="token parameter">iterable</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> l <span class="token operator">=</span> iterable<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i <span class="token operator"><</span> l<span class="token punctuation">;</span> i <span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> iterable<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>resolve<span class="token punctuation">,</span> <span class="token parameter">rea</span> <span class="token operator">=></span> <span class="token punctuation">{</span> count<span class="token operator">++</span><span class="token punctuation">;</span> arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> rea<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>count <span class="token operator">===</span> l<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">AggregateError</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>Promise 有三种状态 pending、fulfilled 和 rejected,pending 是最初的状态,一旦落定为 fulfilled 或 rejected 状态,就不可逆。且一旦执行 resolve 或 reject,后面的 resolve 或 reject 就不会生效。then 传入的回调函数有可能延迟执行,所以需放到 callbacks 数组中,等状态变更的时候再取出执行。最后如果想要测试所写的 Promise 正不正确,可以使用 <a href="https://github.com/promises-aplus/promises-tests#readme">promises-aplus-tests</a> 这个包测试。</p><h3 id="写在后面"><a href="#写在后面" class="headerlink" title="写在后面"></a>写在后面</h3><p>有些代码可能需要不断消化才能理解透彻(大佬除外),笔者也是花了好几周时间,参考了很多资料,对代码不断验证才成此文,如果能够对你有一点小小帮助的话,那将是我最大的欣慰。如果你觉得能学到一点东西的话,还请动动你可爱的小指让更多人看到。如果有错误或者有疑问的地方,欢迎交流讨论。</p><p>参考资料</p><p><a href="https://juejin.cn/post/6844903856489365518">https://juejin.cn/post/6844903856489365518</a></p><p><a href="https://github.com/berwin/time-slicing">https://github.com/berwin/time-slicing</a> </p><p><a href="https://github.com/tj/co">CO 模块</a> </p><p><a href="https://mp.weixin.qq.com/s/qdJ0Xd8zTgtetFdlJL3P1g">100 行代码实现 Promises/A+ 规范</a></p>]]></content>
<categories>
<category> 前端 </category>
</categories>
<tags>
<tag> JavaScript </tag>
</tags>
</entry>
<entry>
<title>JavaScript中那些你傻傻分不清楚的二进制对象</title>
<link href="2021/02/24/frontend/javascript-zhong-na-xie-ni-sha-sha-fen-bu-qing-chu-de-er-jin-zhi-dui-xiang/"/>
<url>2021/02/24/frontend/javascript-zhong-na-xie-ni-sha-sha-fen-bu-qing-chu-de-er-jin-zhi-dui-xiang/</url>
<content type="html"><![CDATA[<p>File继承至Blob</p><p>ArrayBuffer TypedArray FileReader FileReaderSync ReadableStream</p><p>使用场景</p><p>ArrayBuffer为canvas而生</p><p>文件的读取FileReader </p><p>数据的读取Blob</p>]]></content>
<categories>
<category> 前端 </category>
</categories>
<tags>
<tag> JavaScript </tag>
</tags>
</entry>
<entry>
<title>JavaScript中的继承</title>
<link href="2021/01/31/frontend/javascript-zhong-de-ji-cheng/"/>
<url>2021/01/31/frontend/javascript-zhong-de-ji-cheng/</url>
<content type="html"><![CDATA[<blockquote><p>面试中我们经常会被问到继承,希望通过此文,你能彻底搞懂 JavaScript 中的继承原理。</p></blockquote><h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>ES6 以前,JavaScript 中的继承不像其它 oo 语言一样,用特定 class 去实现,它是由构造函数和原型去模拟,下面我们会介绍几种常见的继承方法以及对应的优点和不足。</p><h3 id="原型链"><a href="#原型链" class="headerlink" title="原型链"></a>原型链</h3><h5 id="什么是原型链?"><a href="#什么是原型链?" class="headerlink" title="什么是原型链?"></a>什么是原型链?</h5><p>比如我有一个构造函数,这个构造函数的实例有一个内部指针[[Prototype]]指向构造函数的原型,然后这个构造函数的原型又是另一个构造函数的实例,也就是说这个构造函数原型有一个内部指针[[Prototype]]指向另一个构造函数的原型,如此下去,就构成了一条原型链。那用原型链实现继承用代码表示出来就是这样:</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">Parent</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">'Twittytop'</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token class-name">Parent</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">getName</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">Child</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> <span class="token number">29</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">// 继承</span><span class="token class-name">Child</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Parent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> ins <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Child</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ins<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Twittytop</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>这样原来在 Parent 上的属性都变成了 Child.prototype 上的属性。</p><p><img src="/images/blog/inherit/inherit1.png" alt="inherit1"></p><h5 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h5><p>第一:共享问题</p><p>当 Parent 上包含有引用属性时,就出出现问题,比如:</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">Parent</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>friends <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'Jack'</span><span class="token punctuation">,</span> <span class="token string">'Tom'</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">Child</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> <span class="token number">29</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">// 继承</span><span class="token class-name">Child</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Parent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> ins1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Child</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>ins1<span class="token punctuation">.</span>friends<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">'Bob'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> ins2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Child</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ins2<span class="token punctuation">.</span>friends<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ["Jack", "Tom", "Bob"]</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>因为继承之后变成了 Child 的原型属性,所以所有 Child 的实例都指向的是同一个 friends,当其中一个实例修改了这个值之后,变化就会反映到所有实例上。</p><p>第二: 传参问题</p><p>Child 在实例化是没法向 Parent 传参,当 Parent 依赖外部传参时,就会导致问题。</p><h3 id="盗用构造函数"><a href="#盗用构造函数" class="headerlink" title="盗用构造函数"></a>盗用构造函数</h3><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">Parent</span> <span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token class-name">Parent</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">getName</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">Child</span> <span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> age</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 继承</span> <span class="token function">Parent</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">var</span> ins <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Child</span><span class="token punctuation">(</span><span class="token string">'Twittytop'</span><span class="token punctuation">,</span> <span class="token number">29</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ins<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Twittytop</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ins<span class="token punctuation">.</span>getName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>可以看到,盗用构造函数的优点是能传递参数,问题是它只能继承实例属性,不能继承原型属性。</p><h3 id="组合继承"><a href="#组合继承" class="headerlink" title="组合继承"></a>组合继承</h3><p>既然原型链和盗用构造函数继承都有各自的缺点,那我们能不能把这两者结合起来呢?这就是组合继承。</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">Parent</span> <span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token class-name">Parent</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">getName</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">Child</span> <span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> age</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 继承实例属性</span> <span class="token function">Parent</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">// 继承原型属性</span><span class="token class-name">Child</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Parent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> ins <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Child</span><span class="token punctuation">(</span><span class="token string">'Twittytop'</span><span class="token punctuation">,</span> <span class="token number">29</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ins<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Twittytop</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ins<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Twittytop</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>组合继承弥补了原型链和盗用构造函数的不足,能同时继承实例属性和原型属性,但它的缺点是会调用两次父类构造函数。一次是在 Child 构造函数中执行 Parent.call,一次是在实例化 Parent 时。这样就会导致 Child 的不仅自身实例上有 name 属性,原型上也有 name 属性,导致了不必要的多余继承。用图表示如下:</p><p><img src="/images/blog/inherit/inherit2.png" alt="inherit2"></p><h3 id="原型式继承"><a href="#原型式继承" class="headerlink" title="原型式继承"></a>原型式继承</h3><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">Parent</span> <span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">'Twittytop'</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token class-name">Parent</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">getName</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">Child</span> <span class="token punctuation">(</span><span class="token parameter">age</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">// 继承原型属性</span><span class="token class-name">Child</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token class-name">Parent</span><span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> ins <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Child</span><span class="token punctuation">(</span><span class="token number">29</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ins<span class="token punctuation">.</span>getName<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>原型式继承只继承了原型上的属性,没有继承实例属性,相比原型链继承更干净,它没有把父类的实例属性继承到自身的原型上面,当然,它和原型链一样,也会有引用属性的共享问题。</p><h3 id="寄生式继承"><a href="#寄生式继承" class="headerlink" title="寄生式继承"></a>寄生式继承</h3><p>寄生式继承是建立在原型式继承基础上的,寄生式继承用代码表达出来是这样:</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">inherit</span> <span class="token punctuation">(</span><span class="token parameter">Parent</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> pro <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token class-name">Parent</span><span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span> pro<span class="token punctuation">.</span><span class="token function-variable function">myMethod</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">return</span> pro<span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>它相比原型式继承多了添加一些自己的属性和方法。</p><h3 id="寄生式组合继承"><a href="#寄生式组合继承" class="headerlink" title="寄生式组合继承"></a>寄生式组合继承</h3><p>寄生式组合继承综合了盗用构造函数和寄生式继承,它使用盗用构造函数继承实例属性,使用寄生式继承继承原型属性。</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">inherit</span> <span class="token punctuation">(</span><span class="token parameter">Child<span class="token punctuation">,</span> Parent</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> pro <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token class-name">Parent</span><span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span> pro<span class="token punctuation">.</span>constructor <span class="token operator">=</span> Child<span class="token punctuation">;</span> <span class="token comment">// 将constructor重新指回Child</span> <span class="token class-name">Child</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> pro<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">Parent</span> <span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token class-name">Parent</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">getName</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">Child</span> <span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> age</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 继承实例属性</span> <span class="token function">Parent</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">// 继承原型属性</span><span class="token function">inherit</span><span class="token punctuation">(</span>Child<span class="token punctuation">,</span> Parent<span class="token punctuation">)</span><span class="token keyword">var</span> ins <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Child</span><span class="token punctuation">(</span><span class="token string">'Twittytop'</span><span class="token punctuation">,</span> <span class="token number">29</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ins<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Twittytop</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ins<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Twittytop</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>寄生式组合继承吸取了盗用构造函数和寄生式继承的优点,又没有组合继承中调用父类构造函数两次的不足,是ES5 实现继承的最佳模式。</p><p>关于 ES6 的继承,这里就不介绍了,它本质是上述继承的语法糖而已。</p><h3 id="写在后面"><a href="#写在后面" class="headerlink" title="写在后面"></a>写在后面</h3><p>JavaScript 继承独特的地方就是它的原型,如果这篇文章能让你对 JavaScript 继承有进一步的了解,那将是我最大的欣慰。如果你觉得能学到一点东西的话,还请动动你可爱的小指让更多人看到。如果有错误或者有疑问的地方,也欢迎交流讨论。</p>]]></content>
<categories>
<category> 前端 </category>
</categories>
<tags>
<tag> JavaScript </tag>
</tags>
</entry>
<entry>
<title>盘点 js 中那些诡异的结果</title>
<link href="2021/01/28/frontend/pan-dian-js-zhong-na-xie-gui-yi-de-jie-guo/"/>
<url>2021/01/28/frontend/pan-dian-js-zhong-na-xie-gui-yi-de-jie-guo/</url>
<content type="html"><![CDATA[<pre><code>本文中涉及到的知识,很多都是比较冷门,在实际编码中你可能用不到,但保不准有些面试官可能会问到,或者你可以拿来zb。</code></pre><h3 id="1-typeof-null"><a href="#1-typeof-null" class="headerlink" title="1. typeof null"></a>1. typeof null</h3><p>这个是历史遗留的bug,typeof null 值为”object”</p><h3 id="2-null-undefined"><a href="#2-null-undefined" class="headerlink" title="2. null == undefined"></a>2. null == undefined</h3><p>值为true</p><h3 id="3-0-0"><a href="#3-0-0" class="headerlink" title="3. -0 === +0"></a>3. -0 === +0</h3><p>值为true,但是Object.is(-0, +0)为false</p><h3 id="4-Infinity-0"><a href="#4-Infinity-0" class="headerlink" title="4. Infinity * 0"></a>4. Infinity * 0</h3><p>值为NaN,类似的还有Infinity / Infinity = NaN,Infinity % 0 = NaN,Infinity + (-Infinity) = NaN, </p><h3 id="5-‘a’-lt-3"><a href="#5-‘a’-lt-3" class="headerlink" title="5. ‘a’ < 3"></a>5. ‘a’ < 3</h3><p>值为false,这是因为字符串和数字作比较时,字符串会转化为数值,而’a’转化后的值为NaN,而NaN < 3的值为false,但你以为这样’a’ >= 3就为true了吗?no,’a’ >= 3也为false,这是因为有一个规则,即任何关系操作符在涉及比较NaN时都返回false。</p><h3 id="6-NaN-NaN"><a href="#6-NaN-NaN" class="headerlink" title="6. NaN == NaN"></a>6. NaN == NaN</h3><p>值为false,NaN不是表示某一个具体的数。</p><h3 id="7-window-isNaN-Number-isNaN"><a href="#7-window-isNaN-Number-isNaN" class="headerlink" title="7. window.isNaN != Number.isNaN"></a>7. window.isNaN != Number.isNaN</h3><p>值为true,window.isNaN在早期判断时存在一个bug,比如window.isNaN(‘a’) = true,后来在es6中修复了这个bug,Number.isNaN(‘a’) = false。</p><h3 id="8-typeof-Function-prototype"><a href="#8-typeof-Function-prototype" class="headerlink" title="8. typeof Function.prototype"></a>8. typeof Function.prototype</h3><p>值为”function”,因为Function.prototype是原生方法。</p><h3 id="9-Array-isArray-Array-prototype"><a href="#9-Array-isArray-Array-prototype" class="headerlink" title="9. Array.isArray(Array.prototype)"></a>9. Array.isArray(Array.prototype)</h3><p>值为true,数组的原型也是数组</p><h3 id="10-function-fun-fun-instanceof-Function"><a href="#10-function-fun-fun-instanceof-Function" class="headerlink" title="10. function fun () {}; fun instanceof Function"></a>10. function fun () {}; fun instanceof Function</h3><p>值为true,那<strong>fun instanceof Object</strong>呢?值也为true。关于Object和Function的前世今生,后面会再写一篇文章来说明。</p><h3 id="11-Math-max-‘a’-‘b’"><a href="#11-Math-max-‘a’-‘b’" class="headerlink" title="11. Math.max(‘a’, ‘b’)"></a>11. Math.max(‘a’, ‘b’)</h3><p>值为NaN</p><h3 id="12"><a href="#12" class="headerlink" title="12. [] == ![]"></a>12. [] == ![]</h3><p>值为true,这个题目有一次在笔试的时候被考到过。分析一下,这里涉及到隐式类型转换,首先![]=false,变为[] == false,如果有一操作数为布尔值时,将其转化为number,则变为[] == 0,然后将左边也转换为number,左边是对象,先调用valueOf方法,转换的值为[],不是原始值,所以继续调用toString方法,得到的值为空字符串””,转换为number为0,最终得到0 == 0。</p><p>暂时想到这些,后面有补充再更新。如有疑问,欢迎评论区讨论。</p>]]></content>
<categories>
<category> 前端 </category>
</categories>
<tags>
<tag> JavaScript </tag>
</tags>
</entry>
<entry>
<title>前端知识梳理</title>
<link href="2021/01/28/frontend/qian-duan-zhi-shi-shu-li/"/>
<url>2021/01/28/frontend/qian-duan-zhi-shi-shu-li/</url>
<content type="html"><![CDATA[<h3 id="简历部分"><a href="#简历部分" class="headerlink" title="简历部分"></a>简历部分</h3><h3 id="自我介绍部分"><a href="#自我介绍部分" class="headerlink" title="自我介绍部分"></a>自我介绍部分</h3><h3 id="HTML部分"><a href="#HTML部分" class="headerlink" title="HTML部分"></a>HTML部分</h3><h3 id="CSS部分"><a href="#CSS部分" class="headerlink" title="CSS部分"></a>CSS部分</h3><p>盒模型</p><p>布局</p><p>BFC</p><p>层叠层级</p><h3 id="JavaScript部分"><a href="#JavaScript部分" class="headerlink" title="JavaScript部分"></a>JavaScript部分</h3><p>数据类型</p><p>深拷贝</p><p>继承</p><h3 id="框架部分"><a href="#框架部分" class="headerlink" title="框架部分"></a>框架部分</h3><h3 id="计算机网络"><a href="#计算机网络" class="headerlink" title="计算机网络"></a>计算机网络</h3><h3 id="Web安全"><a href="#Web安全" class="headerlink" title="Web安全"></a>Web安全</h3><h3 id="面试题"><a href="#面试题" class="headerlink" title="面试题"></a>面试题</h3>]]></content>
<categories>
<category> 面试 </category>
</categories>
<tags>
<tag> CSS </tag>
<tag> JavaScript </tag>
<tag> HTML </tag>
<tag> Vue </tag>
</tags>
</entry>
<entry>
<title>mysql-8.0.23的安装</title>
<link href="2021/01/27/tool-instruction/mysql-8.0.23-de-an-zhuang-pei-zhi/"/>
<url>2021/01/27/tool-instruction/mysql-8.0.23-de-an-zhuang-pei-zhi/</url>
<content type="html"><![CDATA[<p>记录一下MySQL 8.0.23的安装配置过程,这里以windows为例</p><h3 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h3><ol><li><p>去官网下载MySQL 8.0.23版本</p><p><img src="/images/blog/MySQL/screenshot1.jpg"></p></li></ol><p> <img src="/images/blog/MySQL/screenshot2.jpg"></p><p> <img src="/images/blog/MySQL/screenshot3.jpg"></p><p> <img src="/images/blog/MySQL/screenshot4.jpg"></p><p> <img src="/images/blog/MySQL/screenshot5.jpg"></p><ol start="2"><li><p>下载完成后解压到自己的安装目录</p><p>我这里的解压目录是: D:\software\mysql-8.0.23-winx64</p></li><li><p>将解压路径配置到环境变量中</p><p>右键此电脑属性 -> 找到高级系统设置配置 -> 环境变量 -> 双击Path,填写你自己的解压路径</p><p><img src="/images/blog/MySQL/screenshot10.jpg"></p><p><img src="/images/blog/MySQL/screenshot11.jpg"></p><p><img src="/images/blog/MySQL/screenshot12.jpg"></p></li><li><p>在解压目录里面新建一个my.ini的配置文件,内容如下:</p><pre class="line-numbers language-ini" data-language="ini"><code class="language-ini"><span class="token selector">[mysqld]</span><span class="token comment"># set basedir to your installation path</span><span class="token constant">basedir</span><span class="token attr-value"><span class="token punctuation">=</span>D:/software/mysql-8.0.23-winx64</span><span class="token comment"># set datadir to the location of your data directory</span><span class="token constant">datadir</span><span class="token attr-value"><span class="token punctuation">=</span>D:/software/mysql-8.0.23-winx64/data</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>然后再新建一个data目录</p></li></ol><h3 id="启动mysql服务器"><a href="#启动mysql服务器" class="headerlink" title="启动mysql服务器"></a>启动mysql服务器</h3><p>这里有2种,一种是安全的,一种是不安全的,实际中你任选一种就行。</p><h5 id="安全的"><a href="#安全的" class="headerlink" title="安全的"></a>安全的</h5><p>通过管理员权限进入cmd,接着键入 <code>mysqld --initialize --console</code> ,然后就会看到如下产生的随机密码,这个密码就是进入MySQL时root用户的初始密码,记下它,如果你不小心关掉了cmd或者没记住,删掉刚才创建的data目录,再执行一遍初始化就会重新生成。</p><p><img src="/images/blog/MySQL/screenshot6.jpg"></p><h5 id="不安全的"><a href="#不安全的" class="headerlink" title="不安全的"></a>不安全的</h5><p>通过管理员权限进入cmd,接着键入 <code>mysqld --initialize-insecure</code>,这种后面不需要输入密码就可以直接进入数据库</p><p>然后键入<code>mysqld --install</code>安装mysql服务,接着键入<code>net start mysql</code>启动服务,就会看到服务成功启动的提示</p><p><img src="/images/blog/MySQL/screenshot7.jpg" alt="screenshot7"></p><h3 id="进入MySQL数据库"><a href="#进入MySQL数据库" class="headerlink" title="进入MySQL数据库"></a>进入MySQL数据库</h3><p> 键入<code>mysql -u root -p</code> ,会提示你输入密码,输入之前记下的密码,然后就会看到如下界面,那么恭喜你,表示你已经成功进入MySQL了</p><p><img src="/images/blog/MySQL/screenshot8.jpg"></p><h3 id="修改密码"><a href="#修改密码" class="headerlink" title="修改密码"></a>修改密码</h3><p> 键入 <code>ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';</code> 出现如下界面,表示更改成功。 </p><p><img src="/images/blog/MySQL/screenshot9.jpg"></p>]]></content>
<categories>
<category> 教程 </category>
</categories>
<tags>
<tag> MySQL </tag>
</tags>
</entry>
<entry>
<title>我的 2020 之路</title>
<link href="2021/01/22/frontend/wo-de-2020-zhi-lu/"/>
<url>2021/01/22/frontend/wo-de-2020-zhi-lu/</url>
<content type="html"><![CDATA[<p>2020是极不平凡又极其有意义的一年,有些东西需要被记录下来。</p><p>以前总对自己记忆力迷之自信,不屑于用文字的形式记录下来(其实是懒),现在发现随着年龄的增长,记忆力愈发衰退,很多东西容易忘记,而记录可以帮助自己回忆当时的很多细节。记录的另外的一个好处是帮助自己复盘,反思自己有哪些地方做得不好,需要改进;有哪些做得还不错,勉励自己继续走下去;有哪些还没有做的,在接下来的时间里需要去弥补。</p><p>2020对我来说最大的一个收获就是儿子和外甥在岁末出生了,这不能不说是一个巨大的惊喜。</p><p>winter说成功三大标准: 1. 年薪百万 2. 知乎十万粉丝 3. 有个好儿子。</p><p>毕竟迈出了第一步,哈哈。但随之而来的你的可支配时间就变少了,下班回来要带娃,周末需要带娃,有时候还需要带去医院检查,当孩子不舒服哭闹的时候,你的睡眠也会受到影响。本来计划很早之前就写一篇对2020的总结的,断断续续地一直拖延到现在。</p><h3 id="戒掉了CF手游"><a href="#戒掉了CF手游" class="headerlink" title="戒掉了CF手游"></a>戒掉了CF手游</h3><p>CF 手游是我一直坚持到现在的一款游戏,可能是因为对当兵有情节的缘故,对射击类的游戏无比喜爱,很享受那种拿着枪射击的感觉。之所以决定放弃它,第一是因为花在它上面的时间有点多了,对生活产生了一些负面的影响;第二是因为有更重要、更有价值的事情要做。当然这里我不是说只要打游戏就是不务正业,如果你觉得游戏能给你的快乐远远大于其他事情给你的快乐,并且没有影响到你的正常生活,那我认为适当的娱乐放松一下也并无不可。我只是觉得对我来说,还有很多其他事情值得我去做,并且能给我带来满足。</p><p><img src="/images/blog/2020-road/CF-M4A1.jpg" alt="CF-M4A1"></p><p>这是一把M4A1-雷神的枪模,我最喜欢也是用得最好的一把枪,当时戒掉CF手游之后买了这个枪模,算是对过往的一个怀念和终结吧。</p><h3 id="忙碌,加班"><a href="#忙碌,加班" class="headerlink" title="忙碌,加班"></a>忙碌,加班</h3><p>在2个月内上线了一个项目,那2个月几乎每天都是11点左右到家,有时候甚至是1点多。因为项目必须得在截止日期之前上线,再加上同时还有其它的项目要处理和人力少的原因,导致时间严重紧张,所以那段时间基本上都是加班加点的在赶工,所幸项目最后能如期上线。记得有一次8点下班,我们公司大爷说: 今天这么早下班啊,很心酸。现在回想起来对那2个月的记忆就是开会,写代码,晚上回去早一点的话就会和媳妇一起散散步。有时候,需要适当的压一压自己,不然你永远不知道其实你能做的还很多。</p><p><img src="/images/blog/2020-road/ticket.jpg" alt="ticket"></p><p>这是当时加班时候打车的发票。</p><h3 id="英语单词"><a href="#英语单词" class="headerlink" title="英语单词"></a>英语单词</h3><p>还算坚持得不错,利用每天早上上班坐地铁的时间背单词,6279个单词学了5512个,还剩52天就能学完剩下单词了。我觉得学好英语还是挺重要的,尤其对于程序员来说,很多时候第一手资料是英文的,英语学得好的话阅读起来就比较轻松。我们部门有一个运营是美国人,有一次快递员送快递给他打电话,由于沟通不畅,他就把电话给了旁边的一位同事,那位同事不知道快递用英文怎么说,就问大家有没有人会说的,刚好我知道,然后就做了快递员和美国同事的翻译,虽然说得不是很流利,但总算完成了交流,还挺洋洋自得的,学过的东西总会有用到的时候。</p><p><img src="/images/blog/2020-road/English1.png" alt="English1"></p><p><img src="/images/blog/2020-road/English2.png" alt="English2"></p><h3 id="读书"><a href="#读书" class="headerlink" title="读书"></a>读书</h3><p>2020读完了《平凡的世界》,《枪炮、病菌与钢铁》看了差不多一半,今年把它看完。记得《平凡的世界》是当时陪女朋友校招,笔试地点是在一个学校,去学校图书馆等她的时候翻到的,当时只看了一点,后来就搁下了。有一天偶然间想起来了这件事,然后就去买了它,就把它看完了。有时候就是这样,看过或听过的某个东西会在你内心里形成一颗小小的种子,虽然你暂时忘记了它,但它会在未来的某一天发芽。看完《平凡的世界》后的一段时间里,还会时时浮现晓霞穿着裙子去工地看少平的情景。</p><p>《枪炮、病菌与钢铁》是一部集地理学、历史学、生物学、医学、哲学于一体的著作。为什么在不同的大陆上人类以如此不同的速度发展呢?通俗点说,为什么是欧洲人殖民了非洲和美洲而不是相反呢?作者花了几十年的时间实地考察,试图去找寻这一问题的答案。有些问题需要你花几十年甚至是一辈子的时间去解答,在这过程中我们需要点科学探索的精神,基于大量的史实、证据去思考,而不是想当然的给出一个答案。</p><p>读书带给我的最大好处是平静,不慌张。我们经常会去刷微博,刷朋友圈,刷新闻等等,不断去接收这些外界的信息,一刻不玩手机心里就会慌乱,生怕和这个世界脱轨,但其实大量的信息对你都是无足轻重的,看和不看根本改变不了什么,而读书的意义在于让你的内心归于宁静,有自己笃定和相信的东西,不被外界的声音所打扰。感谢那段加班后回来翻几页书的夜晚,陪我度过了那段忙碌的时光。不论外界如何喧嚣,都能留有一片属于自己的栖息地。</p><h3 id="诗词"><a href="#诗词" class="headerlink" title="诗词"></a>诗词</h3><p>2020年把唐之韵看了三遍,宋之韵看了2遍,背下并默写了里面的一些诗词,还剩下的一部分在接下来2年内完成。把一些上学时候背诵过的现在有些忘记的诗词重读和背诵了一下,比如滕王阁序、长恨歌、琵琶行、赤壁赋这些,很多有了一些不同的理解。发现自己现在对古诗词越来越感兴趣,想了一下,可能是因为她的简单美。记得我们大学时候的数学分析老师说过,最伟大的定理往往是最简单的定理,意思是说很多伟大的定理往往用寥寥数语表达出来,但其背后却承载了很多东西。诗词也是这样,寥寥数语却包罗万象,使你从不同角度去理解都能得到不一样的感悟,每个字都很平常但你就是写不出这样的诗词来。以前的时候总喜欢在自己手机上加很多额外的配件,比如放个手机壳,贴个贴纸,甚至还买过手机袋,后来都去掉了,还是原始的那一个拿着舒服一些;以前的时候总下很多app,现在总喜欢删app。当你在一个东西上包装很多额外的东西时,往往会掩盖我们最初需要的东西。</p><p><img src="/images/blog/2020-road/note.youdao.com_web_.png" alt="note.youdao.com_web_"></p><p>![note.youdao.com_web_ (1)](/images/blog/2020-road/note.youdao.com_web_ (1).png)</p><p>这是一些默写在有道上的诗。</p><p>这里说一个小故事,前几天去楼下扔垃圾的时候,垃圾分类旁边有一个老爷爷当自愿者看着,老远的时候看到他拿着一张纸在背东西,走近的时候听到是在背《长恨歌》,他是在利用空隙学东西,不禁感慨。老爷爷尚且如此珍惜时间,自己又蹉跎了多少时光。</p><p>最后附上一首去年除夕夜写的一首小诗,那时正值疫情刚爆发,物资、医护人员短缺的时候,即兴写的,写得很一般,有相同爱好的,可以互相交流。</p><p>除夕夜中燃爆竹,不思心头已万绪。<br>问君河山谁沉浮?石壕村里空泪目。</p><h3 id="电影"><a href="#电影" class="headerlink" title="电影"></a>电影</h3><p>看了一些电影,有些是重温,比如《让子弹飞》又看了三遍,加上大学时候看的2遍,总共是看了5遍。记得前2遍看的时候给给我的感觉是搞笑,后三遍看的时候看到了悲哀。之所以重新去看,是因为之前看的时候总感觉有很多地方没看懂,后面看的时候会刻意去注意一些细节,然后会有一些新的感悟。《教父》三部看了一遍,“在一秒钟内看到事情本质的人和花半辈子也看不清一件事本质的人,自然是不一样的命运”给了我极大的冲击;喜欢《七宗罪》里面摩根·弗里曼去图书室查阅书籍时说的一句话:“所有这些书,整个知识的世界触手可得,而你们在干什么”。然后也看了《角斗士》,重看了《肖申克的救赎》和《低俗小说》,《低俗小说》第一遍看的时候完全没看懂作者想表达的什么,所以又重新看了一遍。今年也还是会挑战几部之前没看懂或没完全看懂的电影。</p><p>坚持追了《奇葩说》,从第一季一直到现在第七季, 希望今年能去现场看看。 </p><h3 id="技术文章"><a href="#技术文章" class="headerlink" title="技术文章"></a>技术文章</h3><p>看了社区很多技术文章,技术文章作为对知识的补充或者对某个知识点的理解还是大有裨益的,但是有很多都是自己对一些书籍,文档的再理解,难免出现错误的地方,所以有很多需要自己去亲自实践,不能全信作者所言,我在阅读的过程中就发现了很多勘误。对于有很多碎片化时间的人来说,读公众号类文章帮助自己理解还是挺有好处的。</p><h3 id="收支记录"><a href="#收支记录" class="headerlink" title="收支记录"></a>收支记录</h3><p>对自己的支出作了记录,租房的花费占了大头,其次是日常的生活开支(吃饭、买菜等),收入的话除了理财的收入外基本上都是来自工资了。今年多增加对知识的投资和使收入来源更多样一些。</p><p><img src="/images/blog/2020-road/account.jpg" alt="account"></p><h3 id="一次自驾游"><a href="#一次自驾游" class="headerlink" title="一次自驾游"></a>一次自驾游</h3><p>第一次自驾游,很愉快,野外吃饭,自己带酒,篝火,听着草原歌曲在草原上驰骋,很不错的感受。约上好友,每年去一次,也是一件幸事。</p><h3 id="这一年需要做的"><a href="#这一年需要做的" class="headerlink" title="这一年需要做的"></a>这一年需要做的</h3><ol><li><p>去看一下这个图书馆</p><p><img src="/images/blog/2020-road/library1.jpg" alt="library1"></p><p><img src="/images/blog/2020-road/library2.jpg" alt="library2"></p></li></ol><ol start="2"><li><p>去行走,用读书所学去生活,用生活所学去读书。去看看古人踏过的足迹、生活过的地方,去看看异国的风情,去看看少数民族的风俗,去看看其他地方人们的生活习惯。</p></li><li><p>系统梳理前端知识并输出文章。对前端有了一个整体的认识,希望能输出一些高质量的文章。一来是帮助自己理解,二来是回馈社区。</p></li></ol><p>时间匆匆而来,又匆匆而去,希望自己能把握住时光,给时光以生命,而不是给生命以时光。</p>]]></content>
<categories>
<category> 总结 </category>
</categories>
<tags>
<tag> 随笔 </tag>
</tags>
</entry>
<entry>
<title>如何实现一个抽奖转盘</title>
<link href="2021/01/22/frontend/ru-he-shi-xian-yi-ge-chou-jiang-zhuan-pan/"/>
<url>2021/01/22/frontend/ru-he-shi-xian-yi-ge-chou-jiang-zhuan-pan/</url>
<content type="html"><![CDATA[<h3 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a>写在前面</h3><p>本文也适合有搭建博客需求的非技术人员,不需要服务器,不需要域名,手把手教你搭建一个自己的博客。</p><h3 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h3><p>首先安装一个 Node.js 和 git,安装方式同普通软件安装一样,这里就不详述了。然后打开你的终端,输入命令npm install -g hexo-cli 安装hexo,继续输入 hexo init myBlog,初始化一个你的博客项目。至此,你的博客所在文件夹里面就有了如下目录</p>]]></content>
<categories>
<category> 前端 </category>
</categories>
<tags>
<tag> JavaScript </tag>
</tags>
</entry>
<entry>
<title>详解js中0.1+0.2!=0.3</title>
<link href="2021/01/19/frontend/xiang-jie-js-zhong-0.1-0.2-0.3/"/>
<url>2021/01/19/frontend/xiang-jie-js-zhong-0.1-0.2-0.3/</url>
<content type="html"><![CDATA[<p><font size="3">笔者曾经面试被问到过 0.1+0.2 的结果是啥,初看这题你可能心中会想,难道不是0.3吗?但你肯定会觉得没那么简单,那今天我们就来探一探究竟。</font></p><p><font size="4" color="#00c100">1. JavaScript中数字的存储机制</font></p><p><font size="3">在JavaScript中数字是以 <a href="https://en.wikipedia.org/wiki/Floating_point#Internal_representation"><font size="3" color="#4183C4">IEEE 754 双精度64位浮点数</font></a>(需VPN)来存储的,它的表示格式为:</font></p><font size="3"><center> <font size="3" color="#f00"> (s) * (m) * (2 ^ e)</font></center><font size="3">其中s表示符号位,m表示尾数,占52位,e表示指数,占11位,根据ECMAScript 5 规范,e 的范围是 **[-1074, 971]**,这样可以得出js能表示的最大值为1 * (2^53 - 1) * (2^971) = 1.7976931348623157e+308,而这个值恰好是**Number.MAX_VALUE**的值;同理可以推出js能表示的大于0的最小值是1 * 1 * (2 ^ -1074) = 5e-324,这个值恰好是**Number.MIN_VALUE**的值。</font><p><font size="3">这里你可能注意到了,m是52位,能表示的最大值是2 ^ 52 - 1,可这里为什么是53呢?这就涉及到了隐藏位,比如1 * 1.00111100 * 2 ^ -3中,m表示的是1.00111100中的小数部分“00111100”,整数部分1就是隐藏位,这也就是说,只要指数不全为0,那么它的隐藏位就是1。这里顺便提一下,js里整数可以被精确表示的范围是<font size="3" color="#f00">-2 ^ 53 + 1 ~ 2 ^ 53 - 1。</font></font></p><p><font size="4" color="#00c100">2. 数字表示</font></p><p><font size="3">现在我们回到这道题目来,我们知道在计算机中,数字都是以二进制存储的,所以我们要先将0.1和0.2转化成二进制,对于十进制转二进制,整数部分<font size="3" color="#f00">除二取余,倒序排列</font>,小数部分<font size="3" color="#f00">乘二取整,顺序排列</font>,所以</font></p><p><font size="3">0.1 转化为二进制</font></p><p><font size="3">0.0 0011 0011 0011 0011 0011 0011 … (<font size="3" color="#00c100">0011循环</font>)</font></p><p><font size="3">0.2 转化为二进制</font></p><p><font size="3">0.0011 0011 0011 0011 0011 0011 0011 … (<font size="3" color="#00c100">0011循环</font>)</font></p><p><font size="3">然后我们用之前说过的 <font size="3" color="#4183C4 "><a href="https://en.wikipedia.org/wiki/Floating_point#Internal_representation">IEEE 754 双精度64位浮点数</a></font>(需VPN)来表示:</font></p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 0.1</span>e <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">4</span><span class="token punctuation">;</span>m <span class="token operator">=</span> <span class="token number">1.1001100110011001100110011001100110011001100110011010</span> <span class="token punctuation">(</span><span class="token number">52</span>位<span class="token punctuation">)</span><span class="token comment">// 0.2</span>e <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">3</span><span class="token punctuation">;</span>m <span class="token operator">=</span> <span class="token number">1.1001100110011001100110011001100110011001100110011010</span> <span class="token punctuation">(</span><span class="token number">52</span>位<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><font size="3">当然,这里的m指的是小数点后的52位,而小数点前的整数部分1就是前面说过的隐藏位。</font></p><p><font size="3">然后我们把它相加,这里有一个问题,就是指数不一致时,应该怎么处理,一般是往右移,因为即使右边溢出了,损失的精度远远小于左移时的溢出。</font></p><p><font size="2">e = -4; m = 1.1001100110011001100110011001100110011001100110011010 (52位)</font></p><p><font size="2">+</font></p><p><font size="2">e = -3; m = 1.1001100110011001100110011001100110011001100110011010 (52位)</font></p><hr><p><font size="2">e = -3; m = 0.1100110011001100110011001100110011001100110011001101 (52位)</font></p><p><font size="2">+</font></p><p><font size="2">e = -3; m = 1.1001100110011001100110011001100110011001100110011010 (52位)</font></p><hr><p><font size="2">e = -3; m = 10.0110011001100110011001100110011001100110011001100111 (52位)</font></p><hr><p><font size="2">e = -2; m = 1.00110011001100110011001100110011001100110011001100111 (53位)</font></p><p><font size="3">我们看到已经溢出来了(超过了52位),那么这个时候我们就要做四舍五入了,那怎么舍入才能与原来的数最接近呢?比如1.101要保留2位小数,那么结果有可能是1.10和1.11,这个时候两个都是一样近,我们取哪一个呢?规则是保留偶数的那一个,在这里就是保留1.10。</font></p><p><font size="3">回到我们之前的就是取m=1.0011001100110011001100110011001100110011001100110100 (52位) </font></p><p><font size="3">然后我们得到最终的二进制数</font></p><p><font size="3">1.0011001100110011001100110011001100110011001100110100 * 2 ^ -2</font></p><p><font size="3">=0.010011001100110011001100110011001100110011001100110100</font></p><p><font size="3">现在转化为十进制,二进制小数转化为十进制的方法是小数点后<font color="#f00">第一位*2 ^ -1</font>,<font color="#f00">第二位*2 ^ -2</font>,以此类推,最终我们用等比数列的求和公式得到十进制数为<font size="3" color="#f00">0.30000000000000004</font>,所以0.1 + 0.2的最终结果是</font></p><p><font size="3" color="#f00">0.30000000000000004</font></p><p><font size="3">这就是整个推理过程,希望你也能试着推理一下,虽说这属于JavaScript里面比较偏的知识,但对于了解计算机的存储机制还是有好处的。</font></p><p><font size="3">参考 </font></p><p><font size="3" color="#4183C4"><a href="https://www.cnblogs.com/shytong/p/5091600.html">https://www.cnblogs.com/shytong/p/5091600.html</a></font></p></font>]]></content>
<categories>
<category> 前端 </category>
</categories>
<tags>
<tag> JavaScript </tag>
</tags>
</entry>
<entry>
<title>对 Object.defineProperty 的一点探讨</title>
<link href="2021/01/15/frontend/dui-object.defineproperty-de-yi-dian-tan-tao/"/>
<url>2021/01/15/frontend/dui-object.defineproperty-de-yi-dian-tan-tao/</url>
<content type="html"><![CDATA[<h3 id="引子"><a href="#引子" class="headerlink" title="引子"></a>引子</h3><p>最近读高程4的时候,发现里面有一句话“一个属性被定义为不可配置之后,就不能再变回可配置的了。再次调用Object.defineProperty()并修改任何非writable属性会导致错误”,亲自实践之后,发现这句话的后半段说得有点问题。</p><ol><li><h4 id="当writable为true时,修改value属性不会导致错误"><a href="#当writable为true时,修改value属性不会导致错误" class="headerlink" title="当writable为true时,修改value属性不会导致错误"></a>当writable为true时,修改value属性不会导致错误</h4><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>person<span class="token punctuation">,</span> <span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> configurable<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> writable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> value<span class="token operator">:</span> <span class="token string">"Nicholas"</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>person<span class="token punctuation">,</span> <span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> value<span class="token operator">:</span> <span class="token string">"Twittytop"</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ol><ol start="2"><li><h4 id="当writable为true时将它修改为false不会导致错误(enumerable-属性不行)"><a href="#当writable为true时将它修改为false不会导致错误(enumerable-属性不行)" class="headerlink" title="当writable为true时将它修改为false不会导致错误(enumerable 属性不行)"></a>当writable为true时将它修改为false不会导致错误(enumerable 属性不行)</h4><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>person<span class="token punctuation">,</span> <span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> configurable<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> writable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>person<span class="token punctuation">,</span> <span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> writable<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ol><ol start="3"><li><h4 id="当writable为false时将它修改为true也会导致错误"><a href="#当writable为false时将它修改为true也会导致错误" class="headerlink" title="当writable为false时将它修改为true也会导致错误"></a>当writable为false时将它修改为true也会导致错误</h4><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>person<span class="token punctuation">,</span> <span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> configurable<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> value<span class="token operator">:</span> <span class="token string">"Nicholas"</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>person<span class="token punctuation">,</span> <span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> writable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ol><h3 id="关于writable"><a href="#关于writable" class="headerlink" title="关于writable"></a>关于writable</h3><p>当writable为false时,value值如果是一个数组或对象,修改里面的值将不会报错</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>person<span class="token punctuation">,</span> <span class="token string">"friend"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> configurable<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> writable<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> value<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">"Twittytop"</span><span class="token punctuation">,</span> <span class="token string">"Nicholas"</span><span class="token punctuation">]</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>person<span class="token punctuation">.</span>friend<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">"Matt"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>或者</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>person<span class="token punctuation">,</span> <span class="token string">"friend"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> configurable<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> writable<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> value<span class="token operator">:</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">"Twittytop"</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>person<span class="token punctuation">.</span>friend<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"Nicholas"</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="get-和-Object-defineProperty"><a href="#get-和-Object-defineProperty" class="headerlink" title="get 和 Object.defineProperty"></a>get 和 Object.defineProperty</h3><p>当时用get关键字时,它和通过Object.defineProperty定义的get属性有一些细微的差别。</p><p>在class中,当使用get关键字时,属性将被定义在实例的原型上,而使用Object.defineProperty时,属性将被定义在实例上。</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">class</span> <span class="token class-name">Person</span> <span class="token punctuation">{</span> <span class="token keyword">get</span> <span class="token function">name</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">'Twittytop'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token keyword">var</span> p <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p<span class="token punctuation">.</span><span class="token function">hasOwnProperty</span><span class="token punctuation">(</span><span class="token string">'name'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">getPrototypeOf</span><span class="token punctuation">(</span>p<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">hasOwnProperty</span><span class="token punctuation">(</span><span class="token string">'name'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>p<span class="token punctuation">,</span> <span class="token string">'job'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> value<span class="token operator">:</span> <span class="token string">'engineer'</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p<span class="token punctuation">.</span><span class="token function">hasOwnProperty</span><span class="token punctuation">(</span><span class="token string">'job'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>]]></content>
<categories>
<category> 前端 </category>
</categories>
<tags>
<tag> JavaScript </tag>
</tags>
</entry>
<entry>
<title>手把手教你搭建一个自己的的博客</title>
<link href="2021/01/12/tool-instruction/shou-ba-shou-jiao-ni-da-jian-yi-ge-zi-ji-de-bo-ke/"/>
<url>2021/01/12/tool-instruction/shou-ba-shou-jiao-ni-da-jian-yi-ge-zi-ji-de-bo-ke/</url>
<content type="html"><![CDATA[<h3 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a>写在前面</h3><p>本文也适合有搭建博客需求的非技术人员,不需要服务器,不需要域名,手把手教你搭建一个自己的博客。</p><h3 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h3><p>首先安装一个 Node.js 和 git,安装方式同普通软件安装一样,这里就不详述了。然后打开你的终端,输入命令npm install -g hexo-cli 安装hexo,继续输入 hexo init myBlog,初始化一个你的博客项目。至此,你的博客所在文件夹里面就有了如下目录<img src="/images/blog/hexo/screenshot1.jpg"></p><p>然后用 npm run server启动你的本地服务器,然后在你浏览器里面打开<a href="http://localhost:4000,不出意外的话就能看到了你的博客的界面了。">http://localhost:4000,不出意外的话就能看到了你的博客的界面了。</a></p><h3 id="润色"><a href="#润色" class="headerlink" title="润色"></a>润色</h3><p>现在你的博客里面使用的是hexo内置的默认主题,觉得有点丑是吧,那我们换个主题,这里我推荐自己感觉比较好的两个主题:<a href="https://github.com/blinkfox/hexo-theme-matery">https://github.com/blinkfox/hexo-theme-matery</a> 和 <a href="https://github.com/niemingzhao/niemingzhao.github.io%E3%80%82">https://github.com/niemingzhao/niemingzhao.github.io。</a> 好了,我们现在把它安装到我们的本地,执行 git clone <code> https://github.com/blinkfox/hexo-theme-matery.git</code> themes/matery , 然后去matery文件夹下删掉.git文件夹。</p><p>我们去我们的github里面创建一个仓库,名字叫做 <strong>你的github用户名.github.io</strong> ,比如我的用户名是tuhongwei,那么创建的仓库名就是tuhongwei.github.io,至于为什么这样命名,是因为github提供了一个这种形式的域名,可以直接访问到我们仓库里的静态内容。现在我们进入到我们的博客所在的文件夹,执行 git init,接着执行 git remote add origin <你的github用户名.github.io> ,然后把_config.yml里面的theme值修改为matery,接着重启我们的项目,这样你就能看到一个新主题的博客的,对于一些主题的配置,可以参考上述第一个主题的链接地址里面的文档。</p><h3 id="写博客"><a href="#写博客" class="headerlink" title="写博客"></a>写博客</h3><p>现在我们来开始写我们自己的文章了。首先执行 hexo new <文章名>,这样你在source/_posts下面就能看到新建的文件了,然后你就可以在这个文件里面写你的文章啦,这个目录也是你所有博客所在的目录。</p><h3 id="上传到服务器"><a href="#上传到服务器" class="headerlink" title="上传到服务器"></a>上传到服务器</h3><p>现在我们把我们的博客上传到服务器,可以让所有人都能浏览。我们执行以下步骤:</p><ol><li><p> npm install hexo-deployer-git -S</p></li><li><p>在 _config.yml 最后面修改成如下配置:</p><pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">deploy</span><span class="token punctuation">:</span> <span class="token key atrule">type</span><span class="token punctuation">:</span> git <span class="token key atrule">repo</span><span class="token punctuation">:</span> https<span class="token punctuation">:</span>//github.com/<你的github用户名<span class="token punctuation">></span>/<你的github用户名.github.io<span class="token punctuation">></span> <span class="token key atrule">branch</span><span class="token punctuation">:</span> master<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>hexo deploy</p></li></ol><p>现在访问<你的github用户名>.github.io,应该就能看到你的博客内容了。</p><p>截止到目前,你的博客已经搭建完成了,但是有几个问题:</p><ol><li>我们要在多个电脑之间写博客怎么办?</li><li>每次都要执行部署命令,能不能自动部署?</li><li>如果我想写一个小程序博客,难道每次写完我还得再复制一份吗?有没有什么办法能把我们的文章自动同步过去?</li></ol><p>对于想要搭建自己博客的非技术人员,到这里就已经足够了,但是如果你还想让你博客更智能,更方便一些的话,可以继续往下看。</p><p>我们来逐一解决这些问题:</p><p>首先我们可以另建一个source分支来保存我们的源码以便在多个电脑之间同步,然后当我们提交我们的代码的时候就会执行自动部署。</p><ol><li><p>访问 <a href="https://github.com/marketplace/travis-ci">Travis CI</a> ,进行授权<br><img src="/images/blog/hexo/screenshot2.jpg"></p><p><img src="/images/blog/hexo/screenshot3.jpg"></p></li><li><p>你应该会被重定向到 Travis CI 的页面 ,然后从中找到对应的仓库地址,打开开关</p><p><img src="/images/blog/hexo/screenshot4.jpg"></p></li></ol><ol start="3"><li><p>在浏览器新建一个标签页,前往 GitHub <a href="https://github.com/settings/tokens">新建Personal Access Token</a> ,只勾选 repo 的权限并生成一个新的 Token。Token 生成后请复制并保存好。</p></li><li><p>回到 Travis CI,前往你的 repository 的设置页面,在 Environment Variables 下新建一个环境变量,Name 为 GH_TOKEN,Value 为刚才你在 GitHub 生成的 Token。确保 DISPLAY VALUE IN BUILD LOG 保持 不被勾选 避免你的 Token 泄漏。点击 Add 保存。</p><p><img src="/images/blog/hexo/screenshot5.jpg"></p><p><img src="/images/blog/hexo/screenshot6.jpg"></p></li><li><p>在你的 Hexo 站点文件夹中新建一个 .travis.yml 文件,内容如下:</p><pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">os</span><span class="token punctuation">:</span> <span class="token punctuation">-</span> linux<span class="token key atrule">language</span><span class="token punctuation">:</span> node_js<span class="token key atrule">node_js</span><span class="token punctuation">:</span> stable<span class="token key atrule">cache</span><span class="token punctuation">:</span> npm<span class="token key atrule">branches</span><span class="token punctuation">:</span> <span class="token key atrule">only</span><span class="token punctuation">:</span> <span class="token punctuation">-</span> source <span class="token comment"># build source branch only</span><span class="token key atrule">before_install</span><span class="token punctuation">:</span> <span class="token punctuation">-</span> npm install <span class="token punctuation">-</span>g hexo<span class="token punctuation">-</span>cli<span class="token key atrule">install</span><span class="token punctuation">:</span> <span class="token punctuation">-</span> npm install<span class="token key atrule">script</span><span class="token punctuation">:</span> <span class="token punctuation">-</span> hexo generate <span class="token punctuation">-</span><span class="token punctuation">-</span>force <span class="token comment"># generate static files</span><span class="token key atrule">after_success</span><span class="token punctuation">:</span> <span class="token punctuation">-</span> git config <span class="token punctuation">-</span><span class="token punctuation">-</span>local user.name "你的github用户名" <span class="token punctuation">-</span> git config <span class="token punctuation">-</span><span class="token punctuation">-</span>local user.email "你的github邮箱" <span class="token punctuation">-</span> sed <span class="token punctuation">-</span>i "[email protected]<span class="token punctuation">:</span>~https<span class="token punctuation">:</span>//$<span class="token punctuation">{</span>GH_TOKEN<span class="token punctuation">}</span>@github.com/~" _config.yml <span class="token punctuation">-</span> hexo deploy <span class="token punctuation">></span> /dev/null<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>将你的本地仓库推送到github仓库里面,Travis CI就会自动自行构建,并将生成的文件推送到你仓库的master分支上吗</p></li><li><p>访问 https://<你的 GitHub 用户名>.github.io ,你应该就能看到你的博客了。</p></li></ol><h3 id="同步到小程序"><a href="#同步到小程序" class="headerlink" title="同步到小程序"></a>同步到小程序</h3><p>最后我们来聊一下如何将你的写的博客文章同步到微信小程序里面。</p><p>这里我们要用到 hexo-generator-restful 这个插件,首先我们按照这个插件 npm install hexo-generator-restful –save,然后在 _config.ym 里面增加如下配置,根据自己情况调整</p><pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">restful</span><span class="token punctuation">:</span> <span class="token comment"># site 可配置为数组选择性生成某些属性</span> <span class="token comment"># site: ['title', 'subtitle', 'description', 'author', 'since', email', 'favicon', 'avatar']</span> <span class="token key atrule">site</span><span class="token punctuation">:</span> <span class="token boolean important">true</span> <span class="token comment"># hexo.config mix theme.config</span> <span class="token key atrule">posts_size</span><span class="token punctuation">:</span> <span class="token number">10</span> <span class="token comment"># 文章列表分页,0 表示不分页</span> <span class="token key atrule">posts_props</span><span class="token punctuation">:</span> <span class="token comment"># 文章列表项的需要生成的属性</span> <span class="token key atrule">title</span><span class="token punctuation">:</span> <span class="token boolean important">true</span> <span class="token key atrule">slug</span><span class="token punctuation">:</span> <span class="token boolean important">true</span> <span class="token key atrule">date</span><span class="token punctuation">:</span> <span class="token boolean important">true</span> <span class="token key atrule">updated</span><span class="token punctuation">:</span> <span class="token boolean important">true</span> <span class="token key atrule">comments</span><span class="token punctuation">:</span> <span class="token boolean important">true</span> <span class="token key atrule">path</span><span class="token punctuation">:</span> <span class="token boolean important">true</span> <span class="token key atrule">excerpt</span><span class="token punctuation">:</span> <span class="token boolean important">false</span> <span class="token key atrule">cover</span><span class="token punctuation">:</span> <span class="token boolean important">true</span> <span class="token comment"># 封面图,取文章第一张图片</span> <span class="token key atrule">content</span><span class="token punctuation">:</span> <span class="token boolean important">false</span> <span class="token key atrule">keywords</span><span class="token punctuation">:</span> <span class="token boolean important">false</span> <span class="token key atrule">categories</span><span class="token punctuation">:</span> <span class="token boolean important">true</span> <span class="token key atrule">tags</span><span class="token punctuation">:</span> <span class="token boolean important">true</span> <span class="token key atrule">categories</span><span class="token punctuation">:</span> <span class="token boolean important">true</span> <span class="token comment"># 分类数据</span> <span class="token key atrule">use_category_slug</span><span class="token punctuation">:</span> <span class="token boolean important">false</span> <span class="token comment"># Use slug for filename of category data</span> <span class="token key atrule">tags</span><span class="token punctuation">:</span> <span class="token boolean important">true</span> <span class="token comment"># 标签数据</span> <span class="token key atrule">use_tag_slug</span><span class="token punctuation">:</span> <span class="token boolean important">false</span> <span class="token comment"># Use slug for filename of tag data</span> <span class="token key atrule">post</span><span class="token punctuation">:</span> <span class="token boolean important">true</span> <span class="token comment"># 文章数据</span> <span class="token key atrule">pages</span><span class="token punctuation">:</span> <span class="token boolean important">false</span> <span class="token comment"># 额外的 Hexo 页面数据, 如 About</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>最后会生成一个api的文件夹,里面包含了博客数据,小程序可从这里获取数据。</p><h3 id="网站"><a href="#网站" class="headerlink" title="网站"></a>网站</h3><p><a href="https://tuhongwei.github.io/">https://tuhongwei.github.io</a></p><h3 id="小程序"><a href="#小程序" class="headerlink" title="小程序"></a>小程序</h3><p><img src="/images/blog/hexo/miniprogram.jpg" alt="前端天地"></p>]]></content>
<categories>
<category> 教程 </category>
</categories>
<tags>
<tag> Hexo </tag>
<tag> 博客 </tag>
</tags>
</entry>
<entry>
<title>原来深拷贝还可以这么写</title>
<link href="2021/01/11/frontend/yuan-lai-shen-kao-bei-huan-ke-yi-zhe-me-xie/"/>
<url>2021/01/11/frontend/yuan-lai-shen-kao-bei-huan-ke-yi-zhe-me-xie/</url>
<content type="html"><![CDATA[<h3 id="1-最基本的"><a href="#1-最基本的" class="headerlink" title="1. 最基本的"></a>1. 最基本的</h3><h3 id="2-JSON-parse-JSON-stringify"><a href="#2-JSON-parse-JSON-stringify" class="headerlink" title="2. JSON.parse + JSON.stringify"></a>2. JSON.parse + JSON.stringify</h3><h3 id="3-解决递归爆栈"><a href="#3-解决递归爆栈" class="headerlink" title="3. 解决递归爆栈"></a>3. 解决递归爆栈</h3><h3 id="4-解决循环引用"><a href="#4-解决循环引用" class="headerlink" title="4. 解决循环引用"></a>4. 解决循环引用</h3><h3 id="5-高性能版"><a href="#5-高性能版" class="headerlink" title="5. 高性能版"></a>5. 高性能版</h3><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token constant">MY_IMMER</span> <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">'my-immer1'</span><span class="token punctuation">)</span><span class="token keyword">const</span> <span class="token function-variable function">isPlainObject</span> <span class="token operator">=</span> <span class="token parameter">value</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span>value <span class="token operator">||</span> <span class="token keyword">typeof</span> value <span class="token operator">!==</span> <span class="token string">'object'</span> <span class="token operator">||</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token string">'[object Object]'</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">false</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> proto <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">getPrototypeOf</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>proto <span class="token operator">===</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> Ctor <span class="token operator">=</span> <span class="token function">hasOwnProperty</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>proto<span class="token punctuation">,</span> <span class="token string">'constructor'</span><span class="token punctuation">)</span> <span class="token operator">&&</span> proto<span class="token punctuation">.</span>constructor <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token keyword">typeof</span> Ctor <span class="token operator">==</span> <span class="token string">'function'</span> <span class="token operator">&&</span> Ctor <span class="token keyword">instanceof</span> <span class="token class-name">Ctor</span> <span class="token operator">&&</span> <span class="token class-name">Function</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>Ctor<span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token class-name">Function</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>Object<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token keyword">const</span> <span class="token function-variable function">isProxy</span> <span class="token operator">=</span> <span class="token parameter">value</span> <span class="token operator">=></span> <span class="token operator">!</span><span class="token operator">!</span>value <span class="token operator">&&</span> <span class="token operator">!</span><span class="token operator">!</span>value<span class="token punctuation">[</span><span class="token constant">MY_IMMER</span><span class="token punctuation">]</span><span class="token keyword">function</span> <span class="token function">produce</span><span class="token punctuation">(</span><span class="token parameter">baseState<span class="token punctuation">,</span> fn</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> proxies <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> copies <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> objectTraps <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">get</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> key<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>key <span class="token operator">===</span> <span class="token constant">MY_IMMER</span><span class="token punctuation">)</span> <span class="token keyword">return</span> target <span class="token keyword">const</span> data <span class="token operator">=</span> copies<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>target<span class="token punctuation">)</span> <span class="token operator">||</span> target <span class="token keyword">return</span> <span class="token function">getProxy</span><span class="token punctuation">(</span>data<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">set</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> key<span class="token punctuation">,</span> val<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> copy <span class="token operator">=</span> <span class="token function">getCopy</span><span class="token punctuation">(</span>target<span class="token punctuation">)</span> <span class="token keyword">const</span> newValue <span class="token operator">=</span> <span class="token function">getProxy</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span> <span class="token comment">// 这里的判断用于拿 proxy 的 target</span> <span class="token comment">// 否则直接 copy[key] = newValue 的话外部拿到的对象是个 proxy</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>newValue<span class="token punctuation">,</span> <span class="token function">isProxy</span><span class="token punctuation">(</span>newValue<span class="token punctuation">)</span><span class="token punctuation">)</span> copy<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">isProxy</span><span class="token punctuation">(</span>newValue<span class="token punctuation">)</span> <span class="token operator">?</span> newValue<span class="token punctuation">[</span><span class="token constant">MY_IMMER</span><span class="token punctuation">]</span> <span class="token operator">:</span> newValue <span class="token keyword">return</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> <span class="token function-variable function">getProxy</span> <span class="token operator">=</span> <span class="token parameter">data</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isProxy</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> data <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isPlainObject</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token operator">||</span> Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>proxies<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> proxies<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> proxy <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Proxy</span><span class="token punctuation">(</span>data<span class="token punctuation">,</span> objectTraps<span class="token punctuation">)</span> proxies<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>data<span class="token punctuation">,</span> proxy<span class="token punctuation">)</span> <span class="token keyword">return</span> proxy <span class="token punctuation">}</span> <span class="token keyword">return</span> data <span class="token punctuation">}</span> <span class="token keyword">const</span> <span class="token function-variable function">getCopy</span> <span class="token operator">=</span> <span class="token parameter">data</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>copies<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> copies<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> copy <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token operator">?</span> data<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token operator">...</span>data <span class="token punctuation">}</span> copies<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>data<span class="token punctuation">,</span> copy<span class="token punctuation">)</span> <span class="token keyword">return</span> copy <span class="token punctuation">}</span> <span class="token keyword">const</span> <span class="token function-variable function">isChange</span> <span class="token operator">=</span> <span class="token parameter">data</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>proxies<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token operator">||</span> copies<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> <span class="token function-variable function">finalize</span> <span class="token operator">=</span> <span class="token parameter">data</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isPlainObject</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token operator">||</span> Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">isChange</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> data <span class="token punctuation">}</span> <span class="token keyword">const</span> copy <span class="token operator">=</span> <span class="token function">getCopy</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'copies'</span><span class="token punctuation">,</span> copies<span class="token punctuation">)</span> Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>copy<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token parameter">key</span> <span class="token operator">=></span> <span class="token punctuation">{</span> copy<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">finalize</span><span class="token punctuation">(</span>copy<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token keyword">return</span> copy <span class="token punctuation">}</span> <span class="token keyword">return</span> data <span class="token punctuation">}</span> <span class="token keyword">const</span> proxy <span class="token operator">=</span> <span class="token function">getProxy</span><span class="token punctuation">(</span>baseState<span class="token punctuation">)</span> <span class="token function">fn</span><span class="token punctuation">(</span>proxy<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token function">finalize</span><span class="token punctuation">(</span>baseState<span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token keyword">const</span> state <span class="token operator">=</span> <span class="token punctuation">{</span> info<span class="token operator">:</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">'yck'</span><span class="token punctuation">,</span> career<span class="token operator">:</span> <span class="token punctuation">{</span> first<span class="token operator">:</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">'111'</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> data<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">}</span><span class="token keyword">const</span> data <span class="token operator">=</span> <span class="token function">produce</span><span class="token punctuation">(</span>state<span class="token punctuation">,</span> <span class="token parameter">draftState</span> <span class="token operator">=></span> <span class="token punctuation">{</span> draftState<span class="token punctuation">.</span>info<span class="token punctuation">.</span>age <span class="token operator">=</span> <span class="token punctuation">{</span>hhh<span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">}</span> draftState<span class="token punctuation">.</span>info<span class="token punctuation">.</span>career<span class="token punctuation">.</span>first<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">'222'</span><span class="token punctuation">}</span><span class="token punctuation">)</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>data<span class="token punctuation">,</span> state<span class="token punctuation">)</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>data <span class="token operator">===</span> state<span class="token punctuation">.</span>data<span class="token punctuation">)</span> <span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>这个参考自 yck 大佬的文章,有兴趣的可以去看<a href="https://juejin.cn/post/6844904021627502599">原文</a></p><p>参考:</p><p><a href="https://yanhaijing.com/javascript/2018/10/10/clone-deep">https://yanhaijing.com/javascript/2018/10/10/clone-deep</a></p>]]></content>
<categories>
<category> 前端 </category>
</categories>
<tags>
<tag> JavaScript </tag>
</tags>
</entry>
<entry>
<title>初探ServiceWorker</title>
<link href="2020/12/03/frontend/chu-tan-serviceworker/"/>
<url>2020/12/03/frontend/chu-tan-serviceworker/</url>
<content type="html"><![CDATA[<p>咋一看标题,可能你会觉得非常简单,因为这是极其常见的需求,但只有当你真正去实践过,才会发现这并没有想象中那么简单。长久以来,前端开发者们为此殚精竭虑,琢磨出了各种解决办法,本篇文章将利用现代css的威力,去解决这一难题。<br>先从先前所使用的方法及其弊病讲起。</p><h3 id="1-表格布局法"><a href="#1-表格布局法" class="headerlink" title="1.表格布局法"></a>1.表格布局法</h3><pre class="line-numbers language-html" data-language="html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>container<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>content<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> centered text <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><pre class="line-numbers language-css" data-language="css"><code class="language-css"><span class="token selector">.container</span><span class="token punctuation">{</span> <span class="token property">display</span><span class="token punctuation">:</span> table<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 200px<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> yellowgreen<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token selector">.content</span><span class="token punctuation">{</span> <span class="token property">display</span><span class="token punctuation">:</span> table-cell<span class="token punctuation">;</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">vertical-align</span><span class="token punctuation">:</span> middle<span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>利用了表格的显示模式,弊病是需要用到冗余的HTML元素</p><h3 id="2-行内块法"><a href="#2-行内块法" class="headerlink" title="2.行内块法"></a>2.行内块法</h3><pre class="line-numbers language-html" data-language="html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>container<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>content<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> centered text <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><pre class="line-numbers language-css" data-language="css"><code class="language-css"><span class="token selector">.container</span><span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 200px<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> yellowgreen<span class="token punctuation">;</span> <span class="token property">white-space</span><span class="token punctuation">:</span> nowrap<span class="token punctuation">;</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token selector">.container:before</span> <span class="token punctuation">{</span> <span class="token property">content</span><span class="token punctuation">:</span> <span class="token string">''</span><span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> inline-block<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">vertical-align</span><span class="token punctuation">:</span> middle<span class="token punctuation">;</span> <span class="token property">margin-right</span><span class="token punctuation">:</span> -0.25em<span class="token punctuation">;</span> <span class="token comment">/* Adjusts for spacing */</span><span class="token punctuation">}</span><span class="token selector">.content</span><span class="token punctuation">{</span> <span class="token property">display</span><span class="token punctuation">:</span> inline-block<span class="token punctuation">;</span> <span class="token property">vertical-align</span><span class="token punctuation">:</span> middle<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 300px<span class="token punctuation">;</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>利用了行内块元素的vertical-align: middle属性,弊病是也用到了冗余的HTML元素,而且hack的味道很浓</p><h3 id="3-基于绝对定位"><a href="#3-基于绝对定位" class="headerlink" title="3.基于绝对定位"></a>3.基于绝对定位</h3><pre class="line-numbers language-html" data-language="html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>centered<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><pre class="line-numbers language-css" data-language="css"><code class="language-css"><span class="token selector">.centered</span><span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">top</span><span class="token punctuation">:</span> 50%<span class="token punctuation">;</span> <span class="token property">left</span><span class="token punctuation">:</span> 50%<span class="token punctuation">;</span> <span class="token property">margin-top</span><span class="token punctuation">:</span> -3em<span class="token punctuation">;</span> <span class="token comment">/* 6/2 = 3 */</span> <span class="token property">margin-left</span><span class="token punctuation">:</span> -9em<span class="token punctuation">;</span> <span class="token comment">/* 18/2 = 9 */</span> <span class="token property">width</span><span class="token punctuation">:</span> 18em<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 6em<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> yellowgreen<span class="token punctuation">;</span><span class="token punctuation">}</span> <span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>相信这是很多人使用过的方法,先把元素的左上角放置在正中心,然后利用负外边距向上向左移动自身的一半以使它居中。可以看出来,有一个很明显的弊病,就是元素的宽高必须固定。而在通常情况下,元素的宽高是由其内容决定的,也就是不固定的,那么有没有一种属性是相对于其自身作为基准的呢?可能你已经想到了,那就是css3属性中的translate属性,用上述思路,上面代码可以修改为</p><pre class="line-numbers language-css" data-language="css"><code class="language-css"><span class="token selector">.centered</span><span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">top</span><span class="token punctuation">:</span> 50%<span class="token punctuation">;</span> <span class="token property">left</span><span class="token punctuation">:</span> 50%<span class="token punctuation">;</span> <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translate</span><span class="token punctuation">(</span>-50%<span class="token punctuation">,</span> -50%<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> yellowgreen<span class="token punctuation">;</span><span class="token punctuation">}</span> <span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>很简洁,很完美有没有?但是,没有任何一种技巧是完美无缺的,上面这种方法也有一些弊病之处:<br>用了绝对定位,对整个布局影响有时过于强烈<br>如果需要居中的元素在高度上超过了视口,那他的顶部会被视口裁切掉<br>在某些浏览器中,这个方法可能会导致元素显示有一些模糊,这个问题可以用transform: preserve-3d来修复,但很难保证未来不会出问题</p><h3 id="4-基于视口"><a href="#4-基于视口" class="headerlink" title="4.基于视口"></a>4.基于视口</h3><p>假设我们不想使用绝对定位,仍用translate()来把这个元素以其自身宽高的一半为距离来进行移动,那么在缺少left和top的情况下我们怎样把元素的左上角移到正中央呢?可能你会想到用margin,但是margin的百分比是以父元素的宽度来作为基准的,即使对于margin-top和margin-bottom也是这样。好在我们只需基于视口居中,所以我们可以把margin-top的百分比改为以基于视口的高度作为标准。在css的单位里面有一个叫vh的单位,1vh表示视口高度的1%,那么我们可以更新一下我们的代码:</p><pre class="line-numbers language-css" data-language="css"><code class="language-css"><span class="token selector">.centered</span><span class="token punctuation">{</span> <span class="token property">margin-top</span><span class="token punctuation">:</span> 50vh<span class="token punctuation">;</span> <span class="token property">margin-left</span><span class="token punctuation">:</span> 50%<span class="token punctuation">;</span> <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translate</span><span class="token punctuation">(</span>-50%<span class="token punctuation">,</span> -50%<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> yellowgreen<span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>不难看出,这个技巧的最大弊病就是使用性有限,因为它只能基于视口居中</p><h3 id="5-基于flexbox"><a href="#5-基于flexbox" class="headerlink" title="5.基于flexbox"></a>5.基于flexbox</h3><p>如果有对弹性盒子模型不熟悉的同学可以参考阮一峰老师的这篇文章<a href="http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html">http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html</a> </p><pre class="line-numbers language-html" data-language="html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>centered<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>centered text<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><pre class="line-numbers language-css" data-language="css"><code class="language-css"><span class="token selector">.centered1</span><span class="token punctuation">{</span> <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span> <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> yellowgreen<span class="token punctuation">;</span><span class="token punctuation">}</span> <span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>超级简洁有没有?仅仅几行代码就完美地实现了垂直居中,如果要实现水平居中,只需要加上justify-content: center就可以实现,可见现代css的强大威力,解决了多年来让前端工程师头疼的问题。<br>好了,现在你对什么情况下该使用何种垂直居中方式应该有了一个清晰的认识,在项目中你可以根据实际情况选择适合自己的解决方式。</p>]]></content>
<categories>
<category> 前端 </category>
</categories>
<tags>
<tag> JavaScript </tag>
</tags>
</entry>
<entry>
<title>记一次用postMessage实现跨域通信的踩坑之旅</title>
<link href="2020/10/11/frontend/ji-yi-ci-yong-postmessage-shi-xian-kua-yu-tong-xin-de-cai-keng-zhi-lu/"/>
<url>2020/10/11/frontend/ji-yi-ci-yong-postmessage-shi-xian-kua-yu-tong-xin-de-cai-keng-zhi-lu/</url>
<content type="html"><![CDATA[<h3 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h3><p>首先说一下项目背景,我们做的是一个H5游戏平台,平台会接很多游戏,游戏是用iframe嵌入的,游戏会调用SDK执行某些操作,例如获取用户相关信息,支付等。然后遇到的问题是测试有一天测出来有的游戏点浏览器返回的时候无法从游戏页面返回到游戏平台页面,连续点击的时候有可能会返回,当时大致判断可能是游戏有二次跳转,但至于具体为什么跳转会导致返回出现异常以及怎么解决这个问题当时没有深入去研究,因为一来只有少数几款游戏出现,二来游戏页面有退出游戏的按钮,对用户整体使用影响不大,再加上当时还有很多其他开发任务,所以就暂时搁置了。但这个奇怪的问题一直萦绕在我的心里,直到几个月之后的现在开发任务不怎么紧了,就准备好好研究一下这个问题了。</p><h3 id="探索"><a href="#探索" class="headerlink" title="探索"></a>探索</h3><p>为了验证我最初的判断是否正确,询问了一下游戏那边是否有跳转,得到的结果是他们做了游戏分发,意思是他们会把游戏发布到很多渠道上(我们是其中一个渠道),但是他们给渠道的链接不是游戏原始链接,而是一个经过再包装的带有id以标识渠道号的链接,先通过这个链接获取渠道传过来的用户信息,然后再带着用户信息跳转到真正的游戏链接,ok,到这里基本可以确认是跳转导致了这个问题了,那么为什么会导致这个问题呢?我立马写了一个简单的demo准备复现这个问题,但事情远没有这么简单,不然也就不会有这篇文章了对吧。结果是并没有增加历史记录,然后去查原因,猜测可能是跳转的时间点不对,我是直接在子页面里面跳转,没有等待的操作,而原文题是在收到用户信息之后再跳转的,对demo做了一下调整,增加了延时,然后查看历史记录,的确是增加了,导致这个的原因可能是当前历史记录还没有确定,就跳转了,所以只形成了一条历史记录。到这里原因就明了了,回退的时候回退到分发链接,分发链接获取到用户信息之后又发生了跳转,就形成了循环,导致一直退不回去。那么怎么解决这个问题呢?</p><h1 id="解决"><a href="#解决" class="headerlink" title="解决"></a>解决</h1><p>能不能记录浏览器历史记录的条数,如果条数增加说明有跳转,这时候向历史记录push一条状态并监测onpopstate事件,popstate事件触发的时候就go(-2),这样是可以解决</p>]]></content>
<categories>
<category> 前端 </category>
</categories>
<tags>
<tag> JavaScript </tag>
</tags>
</entry>
<entry>
<title>CSS实现居中的几种方式</title>
<link href="2019/04/08/frontend/css-shi-xian-ju-zhong-de-ji-chong-fang-shi/"/>
<url>2019/04/08/frontend/css-shi-xian-ju-zhong-de-ji-chong-fang-shi/</url>
<content type="html"><![CDATA[<p>咋一看标题,可能你会觉得非常简单,因为这是极其常见的需求,但只有当你真正去实践过,才会发现这并没有想象中那么简单。长久以来,前端开发者们为此殚精竭虑,琢磨出了各种解决办法,本篇文章将利用现代css的威力,去解决这一难题。<br>先从先前所使用的方法及其弊病讲起。</p><h3 id="1-表格布局法"><a href="#1-表格布局法" class="headerlink" title="1.表格布局法"></a>1.表格布局法</h3><pre class="line-numbers language-html" data-language="html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>container<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>content<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> centered text <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><pre class="line-numbers language-css" data-language="css"><code class="language-css"><span class="token selector">.container</span><span class="token punctuation">{</span> <span class="token property">display</span><span class="token punctuation">:</span> table<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 200px<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> yellowgreen<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token selector">.content</span><span class="token punctuation">{</span> <span class="token property">display</span><span class="token punctuation">:</span> table-cell<span class="token punctuation">;</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">vertical-align</span><span class="token punctuation">:</span> middle<span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>利用了表格的显示模式,弊病是需要用到冗余的HTML元素</p><h3 id="2-行内块法"><a href="#2-行内块法" class="headerlink" title="2.行内块法"></a>2.行内块法</h3><pre class="line-numbers language-html" data-language="html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>container<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>content<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> centered text <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><pre class="line-numbers language-css" data-language="css"><code class="language-css"><span class="token selector">.container</span><span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 200px<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> yellowgreen<span class="token punctuation">;</span> <span class="token property">white-space</span><span class="token punctuation">:</span> nowrap<span class="token punctuation">;</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token selector">.container:before</span> <span class="token punctuation">{</span> <span class="token property">content</span><span class="token punctuation">:</span> <span class="token string">''</span><span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> inline-block<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">vertical-align</span><span class="token punctuation">:</span> middle<span class="token punctuation">;</span> <span class="token property">margin-right</span><span class="token punctuation">:</span> -0.25em<span class="token punctuation">;</span> <span class="token comment">/* Adjusts for spacing */</span><span class="token punctuation">}</span><span class="token selector">.content</span><span class="token punctuation">{</span> <span class="token property">display</span><span class="token punctuation">:</span> inline-block<span class="token punctuation">;</span> <span class="token property">vertical-align</span><span class="token punctuation">:</span> middle<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 300px<span class="token punctuation">;</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>利用了行内块元素的vertical-align: middle属性,弊病是也用到了冗余的HTML元素,而且hack的味道很浓</p><h3 id="3-基于绝对定位"><a href="#3-基于绝对定位" class="headerlink" title="3.基于绝对定位"></a>3.基于绝对定位</h3><pre class="line-numbers language-html" data-language="html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>centered<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><pre class="line-numbers language-css" data-language="css"><code class="language-css"><span class="token selector">.centered</span><span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">top</span><span class="token punctuation">:</span> 50%<span class="token punctuation">;</span> <span class="token property">left</span><span class="token punctuation">:</span> 50%<span class="token punctuation">;</span> <span class="token property">margin-top</span><span class="token punctuation">:</span> -3em<span class="token punctuation">;</span> <span class="token comment">/* 6/2 = 3 */</span> <span class="token property">margin-left</span><span class="token punctuation">:</span> -9em<span class="token punctuation">;</span> <span class="token comment">/* 18/2 = 9 */</span> <span class="token property">width</span><span class="token punctuation">:</span> 18em<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 6em<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> yellowgreen<span class="token punctuation">;</span><span class="token punctuation">}</span> <span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>相信这是很多人使用过的方法,先把元素的左上角放置在正中心,然后利用负外边距向上向左移动自身的一半以使它居中。可以看出来,有一个很明显的弊病,就是元素的宽高必须固定。而在通常情况下,元素的宽高是由其内容决定的,也就是不固定的,那么有没有一种属性是相对于其自身作为基准的呢?可能你已经想到了,那就是css3属性中的translate属性,用上述思路,上面代码可以修改为</p><pre class="line-numbers language-css" data-language="css"><code class="language-css"><span class="token selector">.centered</span><span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">top</span><span class="token punctuation">:</span> 50%<span class="token punctuation">;</span> <span class="token property">left</span><span class="token punctuation">:</span> 50%<span class="token punctuation">;</span> <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translate</span><span class="token punctuation">(</span>-50%<span class="token punctuation">,</span> -50%<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> yellowgreen<span class="token punctuation">;</span><span class="token punctuation">}</span> <span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>很简洁,很完美有没有?但是,没有任何一种技巧是完美无缺的,上面这种方法也有一些弊病之处:<br>用了绝对定位,对整个布局影响有时过于强烈<br>如果需要居中的元素在高度上超过了视口,那他的顶部会被视口裁切掉<br>在某些浏览器中,这个方法可能会导致元素显示有一些模糊,这个问题可以用transform: preserve-3d来修复,但很难保证未来不会出问题</p><h3 id="4-基于视口"><a href="#4-基于视口" class="headerlink" title="4.基于视口"></a>4.基于视口</h3><p>假设我们不想使用绝对定位,仍用translate()来把这个元素以其自身宽高的一半为距离来进行移动,那么在缺少left和top的情况下我们怎样把元素的左上角移到正中央呢?可能你会想到用margin,但是margin的百分比是以父元素的宽度来作为基准的,即使对于margin-top和margin-bottom也是这样。好在我们只需基于视口居中,所以我们可以把margin-top的百分比改为以基于视口的高度作为标准。在css的单位里面有一个叫vh的单位,1vh表示视口高度的1%,那么我们可以更新一下我们的代码:</p><pre class="line-numbers language-css" data-language="css"><code class="language-css"><span class="token selector">.centered</span><span class="token punctuation">{</span> <span class="token property">margin-top</span><span class="token punctuation">:</span> 50vh<span class="token punctuation">;</span> <span class="token property">margin-left</span><span class="token punctuation">:</span> 50%<span class="token punctuation">;</span> <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translate</span><span class="token punctuation">(</span>-50%<span class="token punctuation">,</span> -50%<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> yellowgreen<span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>不难看出,这个技巧的最大弊病就是使用性有限,因为它只能基于视口居中</p><h3 id="5-基于flexbox"><a href="#5-基于flexbox" class="headerlink" title="5.基于flexbox"></a>5.基于flexbox</h3><p>如果有对弹性盒子模型不熟悉的同学可以参考阮一峰老师的这篇文章<a href="http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html">http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html</a> </p><pre class="line-numbers language-html" data-language="html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>centered<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>centered text<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><pre class="line-numbers language-css" data-language="css"><code class="language-css"><span class="token selector">.centered1</span><span class="token punctuation">{</span> <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span> <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> yellowgreen<span class="token punctuation">;</span><span class="token punctuation">}</span> <span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>超级简洁有没有?仅仅几行代码就完美地实现了垂直居中,如果要实现水平居中,只需要加上justify-content: center就可以实现,可见现代css的强大威力,解决了多年来让前端工程师头疼的问题。<br>好了,现在你对什么情况下该使用何种垂直居中方式应该有了一个清晰的认识,在项目中你可以根据实际情况选择适合自己的解决方式。</p>]]></content>
<categories>
<category> 前端 </category>
</categories>
<tags>
<tag> CSS </tag>
</tags>
</entry>
</search>