-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
487 lines (257 loc) · 420 KB
/
atom.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
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Don't Fall Asleep Now.</title>
<subtitle>a tiny blog</subtitle>
<link href="http://example.com/atom.xml" rel="self"/>
<link href="http://example.com/"/>
<updated>2024-10-21T11:18:12.472Z</updated>
<id>http://example.com/</id>
<author>
<name>TaskManagerOL</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>Interview</title>
<link href="http://example.com/2024/08/31/Interview/"/>
<id>http://example.com/2024/08/31/Interview/</id>
<published>2024-08-31T08:17:29.000Z</published>
<updated>2024-10-21T11:18:12.472Z</updated>
<content type="html"><![CDATA[<h1 id="面试技巧"><a href="#面试技巧" class="headerlink" title="面试技巧"></a>面试技巧</h1><h2 id="简历准备"><a href="#简历准备" class="headerlink" title="简历准备"></a>简历准备</h2><p>Boss是不能先发送简历附件的,要填写线上简历+打招呼内容。</p><h2 id="网申"><a href="#网申" class="headerlink" title="网申"></a>网申</h2><p>HR一般会在上午9点半左右以及下午两点左右打开邮箱,在上午11点、下午三点左右通知你面试;每周二、周五看邮箱的几率稍大。HR的工作顺序是:查看并筛选主动投递简历→看平台推荐人才简历→主动检索简历,打招呼后正常发简历就行。</p><blockquote><p>您好,我对贵司xx职位很感兴趣,请您看下我的简历,如果合适可以随时联系我,谢谢。</p><p>(发送简历)</p></blockquote><p>若已读未回,可能简历处于合适和不合适之间,可以做以下处理:</p><blockquote><p>HR您好,我非常看好贵司机会,此前投递简历后,发现您已读未回,可能是您没来得及处理,也可能是我的简历没有通过筛选,我想确认一下,希望能得到您的回复。谢谢!</p><p>以下是我的微信和电话,如方便,您可以直接给我电话。盼复。</p><p>(发送微信和电话)</p></blockquote><p>若还是已读不回,应该是不合适了,如果还是很想投的话可以考虑找到HR电话致电。</p><h2 id="个人介绍"><a href="#个人介绍" class="headerlink" title="个人介绍"></a>个人介绍</h2><p>面试官您好,很荣幸参加本次面试。</p><p>我叫xxx,今天来面试贵司的前端开发实习生岗位,接下来我做一个简单的自我介绍。</p><p>我是xx届的毕业生,就读xx大学的计算机与信息安全学院,在大学期间自学了Web前端及其相关技能。大一下学期的时候在xxxxx找到一份前端开发的线上实习。</p><p>在实习的时候,主要使用的技术栈和工具就是vue3+element plus,工作内容就是和其他前端一起写前端页面,我是负责写数据管理等页面或者组件,然后通过git平台上传整合,周期交任务写报告之类的,积攒了不少经验。</p><p>最近的项目是我自己写的一个TODO平台,前后端UI设计服务器部署都是我自己做的。之前有团队协作做过小程序项目,用过uniapp但最后在微信开发者平台开发的。</p><p>大学期间也还做过不少其他项目,大部分是在比赛中做的,也拿到了例如网挑国奖的成绩。在学院里担任科技协会主席,逻辑清晰,善于沟通。</p><p>以上就是我的大致情况,谢谢。</p><h1 id="Vue"><a href="#Vue" class="headerlink" title="Vue"></a>Vue</h1><h2 id="VUE3项目目录结构"><a href="#VUE3项目目录结构" class="headerlink" title="VUE3项目目录结构"></a>VUE3项目目录结构</h2><figure class="highlight brainfuck"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs brainfuck"><span class="hljs-comment">| node_modules</span><span class="hljs-literal">--</span><span class="hljs-comment">项目依赖</span><br><span class="hljs-comment">| public </span><span class="hljs-literal">--</span><span class="hljs-comment">公共文件夹</span><br><span class="hljs-literal">---</span><span class="hljs-comment">| favicon</span><span class="hljs-string">.</span><span class="hljs-comment">ico</span><span class="hljs-literal">--</span><span class="hljs-comment">网站图标</span><br><span class="hljs-comment">| src </span><span class="hljs-literal">--</span><span class="hljs-comment">源文件目录</span><br><span class="hljs-literal">---</span><span class="hljs-comment">| assets</span> <span class="hljs-literal">--</span><span class="hljs-comment">静态文件</span><br><span class="hljs-comment"></span><span class="hljs-literal">---</span><span class="hljs-comment">| utils</span> <span class="hljs-literal">--</span><span class="hljs-comment">工具类JS</span><br><span class="hljs-comment"></span><span class="hljs-literal">---</span><span class="hljs-comment">| api</span> <span class="hljs-literal">--</span><span class="hljs-comment">接口类JS</span><br><span class="hljs-literal">---</span><span class="hljs-comment">| components</span><span class="hljs-literal">--</span><span class="hljs-comment">组件</span><br><span class="hljs-literal">---</span><span class="hljs-comment">| router</span><span class="hljs-literal">--</span><span class="hljs-comment">路由配置</span><br><span class="hljs-literal">---</span><span class="hljs-comment">| store</span><span class="hljs-literal">--</span><span class="hljs-comment">状态管理器</span><br><span class="hljs-literal">---</span><span class="hljs-comment">| views</span><span class="hljs-literal">--</span><span class="hljs-comment">视图文件,与路由结构对应</span><br><span class="hljs-literal">---</span><span class="hljs-comment">| App</span><span class="hljs-string">.</span><span class="hljs-comment">vue</span><span class="hljs-literal">--</span><span class="hljs-comment">根组件</span><br><span class="hljs-literal">---</span><span class="hljs-comment">| main</span><span class="hljs-string">.</span><span class="hljs-comment">js </span><span class="hljs-literal">--</span><span class="hljs-comment">入口文件</span><br><span class="hljs-comment">| index</span><span class="hljs-string">.</span><span class="hljs-comment">html</span><span class="hljs-literal">--</span><span class="hljs-comment">入口html</span><br><span class="hljs-comment">| package</span><span class="hljs-string">.</span><span class="hljs-comment">json</span><span class="hljs-literal">--</span><span class="hljs-comment">命令配置及依赖管理</span><br><span class="hljs-comment">| package</span><span class="hljs-literal">-</span><span class="hljs-comment">lock</span><span class="hljs-string">.</span><span class="hljs-comment">json</span><span class="hljs-literal">--</span><span class="hljs-comment">依赖版本及更完整的依赖树</span><br><span class="hljs-comment">| README</span><span class="hljs-string">.</span><span class="hljs-comment">md</span><span class="hljs-literal">--</span><span class="hljs-comment">说明文件</span><br><span class="hljs-comment">| vue</span><span class="hljs-string">.</span><span class="hljs-comment">config</span><span class="hljs-string">.</span><span class="hljs-comment">json </span> <span class="hljs-literal">--</span><span class="hljs-comment">代理、打包等配置文件</span><br></code></pre></td></tr></table></figure><hr><blockquote><h3 id="public和assets区别:"><a href="#public和assets区别:" class="headerlink" title="public和assets区别:"></a>public和assets区别:</h3><p>同样用于存放静态文件的文件夹。由于vue-cli、vite等工具打包时,public下的文件会原封不动的添加到dist中,而assets下的文件会被合并压缩。</p><p>两者的区别是public下一般用于放有更新需求的第三方插件、图片且需要使用绝对路径来引用(否则会warning),而assets下适合用于存放项目中所必须的图标、JS文件只支持相对路径。<a href="https://vitejs.cn/vite3-cn/guide/assets.html#importing-asset-as-url">相关文档</a></p></blockquote><hr><blockquote><h3 id="有了package-json为什么还需要package-lock-json:"><a href="#有了package-json为什么还需要package-lock-json:" class="headerlink" title="有了package.json为什么还需要package-lock.json:"></a>有了package.json为什么还需要package-lock.json:</h3><p>前者声明依赖的种类而后者决定实际安装的版本,使用<code>npm install</code>时就是根据package-lock.json进行安装。</p></blockquote><h1 id="Javascript"><a href="#Javascript" class="headerlink" title="Javascript"></a>Javascript</h1><h2 id="ECMA-262标准化语言规范"><a href="#ECMA-262标准化语言规范" class="headerlink" title="ECMA-262标准化语言规范"></a>ECMA-262标准化语言规范</h2><blockquote><h3 id="ECMAScript和Javascript的区别"><a href="#ECMAScript和Javascript的区别" class="headerlink" title="ECMAScript和Javascript的区别:"></a>ECMAScript和Javascript的区别:</h3><p>ECMAScript是JavaScript的核心语言规范,而JavaScript则是基于这些规范的具体实现,包含了更多的功能和API,以便在浏览器和其他环境中运行。</p></blockquote><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br></pre></td><td class="code"><pre><code class="hljs markdown">ES1(1997年)<br><span class="hljs-bullet">+</span> 基于Netscape的JavaScript 1.1。<br><br>ES2(1998年)<br><span class="hljs-bullet">+</span> 与ISO/IEC 16262标准保持一致。<br><br>ES3(1999年):<br><span class="hljs-bullet">+</span> 正则表达式:引入了正则表达式支持。<br><span class="hljs-bullet">+</span> 更好的字符串处理:增加了新的字符串方法。<br><span class="hljs-bullet">+</span> 控制语句:添加了try/catch异常处理。<br><span class="hljs-bullet">+</span> 其他改进:包括更严格的错误定义和数字格式化。<br><br>ES5(2009年):<br><span class="hljs-bullet">+</span> 严格模式:提供了更严格的错误检查。<br><span class="hljs-bullet">+</span> JSON支持:内置了对JSON的支持。<br><span class="hljs-bullet">+</span> Array方法:如forEach、map、filter等。<br><span class="hljs-bullet">+</span> Object方法:如Object.keys、Object.defineProperty等。<br><br>ES6(2015年):<br><span class="hljs-bullet">+</span> 箭头函数:简化了函数表达式。<br><span class="hljs-bullet">+</span> let和const:引入了块级作用域变量。<br><span class="hljs-bullet">+</span> 模板字符串:支持多行字符串<span class="hljs-code">` `</span> 和内嵌表达式${ }。<br><span class="hljs-bullet">+</span> 类和模块:引入了类和模块系统。<br><span class="hljs-bullet">+</span> Promise:用于处理异步操作。<br><br>ES7(2016年):数组includes方法、指数运算简化<br><span class="hljs-bullet">+</span> Array.prototype.includes():检查数组中是否包含某个元素。<br><span class="hljs-bullet">+</span> 指数运算符:简化指数运算为双星号。<br><br>ES8(2017年):简化异步、对象方法优化、字符串填充方法<br><span class="hljs-bullet">+</span> Async/Await:简化异步代码。<br><span class="hljs-bullet">+</span> Object.values() 和 Object.entries():返回对象的值和键值对数组。<br><span class="hljs-bullet">+</span> String padding:字符串填充方法。<br><br>ES9(2018年):<br><span class="hljs-bullet">+</span> 异步迭代器:支持异步数据流处理。<br><span class="hljs-bullet">+</span> Rest/Spread属性:(...)扩展对象的解构赋值和扩展运算符。<br><br>ES10(2019年)数组/对象/字符串处理方法增加<br><span class="hljs-bullet">+</span> Array.prototype.flat() 和 Array.prototype.flatMap():数组扁平化方法。<br><span class="hljs-bullet">+</span> Object.fromEntries():将键值对列表转换为对象。<br><span class="hljs-bullet">+</span> String.prototype.trimStart() 和 String.prototype.trimEnd():去除字符串开头和结尾的空白字符。<br><br>ES11(2020年):BigInt、空值合并、动态导入模块、可选链<br><span class="hljs-bullet">+</span> BigInt:支持任意精度的整数。<br><span class="hljs-bullet">+</span> 动态导入:按需加载模块。<br><span class="hljs-bullet">+</span> 空值合并运算符(??):处理null或undefined。<br><span class="hljs-bullet">+</span> 可选链运算符(?.):简化深层嵌套对象属性的访问。<br><br>ES12(2021年):逻辑赋值运算、字符串匹配方法<br><span class="hljs-bullet">+</span> 逻辑赋值运算符(&&=、||=、??=):结合逻辑运算和赋值操作。<br><span class="hljs-bullet">+</span> String.prototype.replaceAll():替换字符串中所有匹配的子串。<br><span class="hljs-bullet">+</span> Promise.any():返回第一个成功的Promise。<br><br>ES13(2022年)顶层await、类字段声明初始化<br><span class="hljs-bullet">+</span> 顶层await:在模块顶层使用await。<br><span class="hljs-bullet">+</span> 类字段声明:简化类中字段的声明和初始化。<br><br>ES14(2023年)数组方法优化<br><span class="hljs-bullet">+</span> Array.prototype.toSorted():返回排序后的数组副本。<br><span class="hljs-bullet">+</span> Array.prototype.toReversed():返回反转后的数组副本。<br><span class="hljs-bullet">+</span> Array.prototype.toSpliced():返回删除或替换元素后的数组副本。<br><br>ES15(2024年)symbol描述、匹配字符串索引<br><span class="hljs-bullet">+</span> RegExp Match Indices:提供匹配子字符串的索引。<br><span class="hljs-bullet">+</span> Symbol.prototype.description:返回Symbol的描述。<br></code></pre></td></tr></table></figure><h2 id="数据类型"><a href="#数据类型" class="headerlink" title="数据类型"></a>数据类型</h2><blockquote><h3 id="基本类型:"><a href="#基本类型:" class="headerlink" title="基本类型:"></a>基本类型:</h3><p>基本类型有六种。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//Number</span><br><span class="hljs-keyword">let</span> intNum = <span class="hljs-number">1</span>,octNum = <span class="hljs-number">001</span>,hexNum = <span class="hljs-number">0x1</span> <span class="hljs-comment">//整数,常见十进制、八进制、十六进制</span><br><span class="hljs-keyword">let</span> floatNum = <span class="hljs-number">0.1</span>,eNum = <span class="hljs-number">1.11e7</span><span class="hljs-comment">//可以表示科学计数法e后面是幂</span><br><span class="hljs-title function_">log</span>(<span class="hljs-number">0</span>/<span class="hljs-number">0</span>) <span class="hljs-comment">//返回NaN 意思是本来返回数值的操作失败</span><br></code></pre></td></tr></table></figure><hr><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//Undefined</span><br><span class="hljs-keyword">let</span> message,<span class="hljs-title function_">log</span>(message)<span class="hljs-comment">//返回undefined,变量声明过但未被初始化。</span><br></code></pre></td></tr></table></figure><hr><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//String</span><br><span class="hljs-keyword">let</span> <span class="hljs-title class_">AStr</span> = <span class="hljs-string">"1"</span>,aStr = <span class="hljs-string">'1'</span>,someStr = <span class="hljs-string">`1`</span><span class="hljs-comment">//字符串一旦被创建,值就不可以再被改变,如果执行改变的操作,会先销毁再创建。</span><br></code></pre></td></tr></table></figure><hr><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//Null</span><br><span class="hljs-keyword">let</span> nullOne = <span class="hljs-literal">null</span>,<span class="hljs-title function_">log</span>(<span class="hljs-keyword">typeof</span> nullOne)<span class="hljs-comment">//null是一个空对象指针,输出为Object,如果变量要保存对象,但是当时又没有对象可以保存,就用null填充。</span><br><span class="hljs-title function_">log</span>(<span class="hljs-literal">null</span>==<span class="hljs-literal">undefined</span>)<span class="hljs-comment">//undefined是由null派生来的,返回为真</span><br></code></pre></td></tr></table></figure><hr><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//Boolean</span><br><span class="hljs-comment">//对于非空字符串、数值、对象、N/A 转为布尔值为true</span><br><span class="hljs-comment">//对于""、0、NaN、null、undefined 转为布尔值为false</span><br></code></pre></td></tr></table></figure><hr><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//Symbol</span><br><span class="hljs-keyword">let</span> aSymbol = <span class="hljs-title class_">Symbol</span>(<span class="hljs-string">'1'</span>),bSymbol = <span class="hljs-title class_">Symbol</span>(<span class="hljs-string">'1'</span>),<span class="hljs-title function_">log</span>(aSymbol==bSymbol)<span class="hljs-comment">//返回false,symbol是原始值,symbol实例是唯一且不可变的,symbol的作用是确保对象属性使用唯一标识符。</span><br></code></pre></td></tr></table></figure></blockquote><hr><blockquote><h3 id="引用类型:"><a href="#引用类型:" class="headerlink" title="引用类型:"></a>引用类型:</h3><p>引用类型统称为<code>object</code>,包括<code>object</code> <code>array</code> <code>function</code> <code>Date</code> <code>RegExp</code> <code>Map</code> <code>Set</code> </p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//Object对象</span><br><span class="hljs-keyword">let</span> man = { <span class="hljs-comment">// 属性名可以是字符串或者数值</span><br><span class="hljs-attr">name</span>:<span class="hljs-string">"zero"</span>,<br><span class="hljs-string">"age"</span>:<span class="hljs-number">1</span>,<br><span class="hljs-number">1</span>:<span class="hljs-literal">true</span><br>}<br></code></pre></td></tr></table></figure><hr><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//Array</span><br><span class="hljs-keyword">let</span> colors = [<span class="hljs-string">"red"</span>, <span class="hljs-number">2</span>, {<span class="hljs-attr">age</span>: <span class="hljs-number">20</span> }] <span class="hljs-comment">//JS数组是动态大小的,每个槽位可以存储任意类型数据的。</span><br></code></pre></td></tr></table></figure><hr><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//Function</span><br><span class="hljs-keyword">let</span> <span class="hljs-title function_">sum</span> = (<span class="hljs-params">num1, num2</span>) => {<br> <span class="hljs-keyword">return</span> num1 + num2;<br>};<br></code></pre></td></tr></table></figure></blockquote><hr><blockquote><h3 id="区别:"><a href="#区别:" class="headerlink" title="区别:"></a>区别:</h3><p>基本数据类型和引用数据类型存储在内存中的位置不同:</p><ul><li>基本数据类型存储在栈中</li><li>引用类型的对象存储于堆中</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">let</span> a = <span class="hljs-number">10</span>;<br><span class="hljs-keyword">let</span> b = a; <span class="hljs-comment">// 赋值操作</span><br>b = <span class="hljs-number">20</span>;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(a); <span class="hljs-comment">// 10值</span><br><br><span class="hljs-keyword">var</span> obj1 = {}<br><span class="hljs-keyword">var</span> obj2 = obj1;<span class="hljs-comment">//这个操作让obj1和2的引用地址相同了。</span><br>obj2.<span class="hljs-property">name</span> = <span class="hljs-string">"1"</span>;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj1.<span class="hljs-property">name</span>); <span class="hljs-comment">// 1</span><br></code></pre></td></tr></table></figure></blockquote><h2 id="Iterator相关知识"><a href="#Iterator相关知识" class="headerlink" title="Iterator相关知识"></a>Iterator相关知识</h2><blockquote><h3 id="迭代器生成方式及使用方式:"><a href="#迭代器生成方式及使用方式:" class="headerlink" title="迭代器生成方式及使用方式:"></a>迭代器生成方式及使用方式:</h3><p>某些方法会返回一个迭代器,如<code>arr.entries()</code>返回一个带有全部键值对的迭代器,使用<code>next()</code>方法返回迭代器结果对象。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">const</span> array1 = [<span class="hljs-string">'a'</span>, <span class="hljs-string">'b'</span>, <span class="hljs-string">'c'</span>];<br><br><span class="hljs-keyword">const</span> iterator1 = array1.<span class="hljs-title function_">entries</span>();<br><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(iterator1.<span class="hljs-title function_">next</span>().<span class="hljs-property">value</span>);<br><span class="hljs-comment">// Expected output: Array [0, "a"]</span><br><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(iterator1.<span class="hljs-title function_">next</span>().<span class="hljs-property">value</span>);<br><span class="hljs-comment">// Expected output: Array [1, "b"]</span><br></code></pre></td></tr></table></figure></blockquote><h2 id="Array相关知识"><a href="#Array相关知识" class="headerlink" title="Array相关知识"></a>Array相关知识</h2><blockquote><h3 id="数组长度与空槽:"><a href="#数组长度与空槽:" class="headerlink" title="数组长度与空槽:"></a>数组长度与空槽:</h3><p><code>arr.length</code>可以输出数组长度,甚至可以更改<code>arr.length</code>去改变数组长度,如果用此法扩展数组长度,没有被赋值的地方会产生<code>空槽</code>,<code>空槽</code>无法输出,对于不同数组方法,<code>空槽</code>也有不同的行为。</p><p>如<code>forEach</code>等迭代方法根本不会访问空槽。而其他的拼接复制方法如<code>concat</code>则会保留空槽。一些较新的方法会视其为undefined 如<code>splice()</code>拼接数组,<code>join()</code>等。</p></blockquote><hr><blockquote><h3 id="常用的数组方法:"><a href="#常用的数组方法:" class="headerlink" title="常用的数组方法:"></a>常用的数组方法:</h3><ul><li><code>every()/some()</code>-对数组内所有元素执行括号内函数,全部通过/有一个通过返回布尔值。</li><li><code>fill(target,start,end)</code>-对数组内指定索引覆盖target值,超出范围不会扩展数组。</li><li><code>find()/findLast()</code>-返回括号内函数符合条件的第一个/最后一个值,否则返回undefined。</li><li><code>findIndex()/findLastIndex()</code>-返回括号内函数符合条件的第一个/最后一个索引,否则返回undefined。</li><li><code>indexOf()/lastIndexOf()</code>-返回括号内值符合条件的第一个值/最后一个值的索引,否则返回-1。</li><li><code>flat()</code>-扁平化数组,括号内为深度,ES10新语法</li><li><code>includes()</code>-判断数组是否包含一个值,返回布尔值,ES7新语法</li><li><code>join()</code>-将一个数组更改为其各元素以括号内字符串连接的字符串,默认使用逗号,如目标数组不是纯数组,报错。</li><li><code>pop()/push()</code>-移除/添加数组末尾一个元素并返回该值,如果push的是一个数组则会在末尾添加数组,push自身会导致循环引用。</li><li><code>shift()/unshift()</code>-移除/添加数组第一个元素并返回该值</li><li><code>reverse()/toReversed()</code>-转置原数组改变原数组/转置原数组不改变原数组,<code>toReversed()</code>ES14新语法</li><li><code>slice(start,end)</code>-浅拷贝一个由start开始end结束的数组,不改变原数组。</li><li><code>sort()/toSorted()</code>-对数组按照元素第一个字符的ascii码排序改变原数组/不改变原数组</li><li><code>splice(start,num,value...)/toSpliced()</code>-删除由start开始的num个数值,并在start索引下添加value值,改变原数组/不改变原数组。</li></ul></blockquote><hr><blockquote><h3 id="forEach、filter、map、reduce的区别"><a href="#forEach、filter、map、reduce的区别" class="headerlink" title="forEach、filter、map、reduce的区别:"></a>forEach、filter、map、reduce的区别:</h3><p>三者都是ES5的新特性,均用于数组。</p><p><code>forEach</code>遍历数组全部元素并对数组进行操作,不返回新数组,return用于跳出循环,返回undefined。</p><p><code>filter</code>遍历数组全部元素并使用判断语句返回新数组,return值为假的时候过滤。</p><p><code>map</code>遍历数组全部元素并操作数组产生新数组,不改变原数组。</p><p><code>reduce((accumulator, currentValue)=>...,initialValue)</code>-遍历数组,若initialValue设置则为初始accumulator值,若没设置则currentValue为数组第一个值,不可处理数组对象,…处不可以加大括号。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//设分别执行三种函数</span><br><span class="hljs-keyword">let</span> arr = [<br> {<span class="hljs-attr">name</span>:<span class="hljs-string">'小明'</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">14</span>},<br> {<span class="hljs-attr">name</span>:<span class="hljs-string">'小华'</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">11</span>},<br> {<span class="hljs-attr">name</span>:<span class="hljs-string">'小红'</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">15</span>},<br> {<span class="hljs-attr">name</span>:<span class="hljs-string">'小黄'</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">17</span>},<br>]<br><br><span class="hljs-keyword">let</span> forEachBack = arr.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">item</span> =></span> {<br> item.<span class="hljs-property">name</span> = <span class="hljs-string">"学生"</span>+item.<span class="hljs-property">name</span><br>})<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(forEachBack)<span class="hljs-comment">//undefined</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(arr)<span class="hljs-comment">//name前都加上学生</span><br><br><span class="hljs-keyword">let</span> filterBack = arr.<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">item</span> =></span> {<br> <span class="hljs-keyword">return</span> item.<span class="hljs-property">age</span>><span class="hljs-number">10</span><br>})<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(filterBack)<span class="hljs-comment">//包含有name属性的,每一项age大于10的新数组</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(arr)<span class="hljs-comment">//arr不变</span><br><br><span class="hljs-keyword">let</span> filterBack = arr.<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">item</span> =></span> {<br> <span class="hljs-keyword">return</span> item.<span class="hljs-property">age</span>><span class="hljs-number">10</span><br>})<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(filterBack)<span class="hljs-comment">//包含有name属性的,每一项age大于10的新数组</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(arr)<span class="hljs-comment">//arr不变</span><br><br><span class="hljs-keyword">let</span> mapBack = arr.<span class="hljs-title function_">map</span>(<span class="hljs-function"><span class="hljs-params">item</span> =></span> {<br> <span class="hljs-keyword">return</span> item.<span class="hljs-property">age</span> + <span class="hljs-number">1</span><br>})<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(mapBack)<span class="hljs-comment">//不包含有name属性的,每一项age加1的新一维数组:[15,12,16,18]</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(arr)<span class="hljs-comment">//arr不变</span><br><br><span class="hljs-keyword">let</span> initialValue = -<span class="hljs-number">1</span>;<br><span class="hljs-keyword">let</span> reduceBack = mapBack.<span class="hljs-title function_">reduce</span>(<br><span class="hljs-function">(<span class="hljs-params">accumulator, currentValue</span>) =></span> accumulator + currentValue,<br>initialValue<br>);<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(reduceBack)<span class="hljs-comment">//60 = -1 + 15 + 12 + 16 +18</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(arr)<span class="hljs-comment">//arr不变</span><br></code></pre></td></tr></table></figure></blockquote><h2 id="String相关知识"><a href="#String相关知识" class="headerlink" title="String相关知识"></a>String相关知识</h2><p><code>String()</code>作为函数调用时,返回字面量原始值。<code>String()</code>作为构造函数(使用<code>new</code>)被调用时,会创建一个String对象,该对象不是原始类型。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">const</span> a = <span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>(<span class="hljs-string">"Hello world"</span>); <span class="hljs-comment">// a === "Hello world" 为 false</span><br><span class="hljs-keyword">const</span> b = <span class="hljs-title class_">String</span>(<span class="hljs-string">"Hello world"</span>); <span class="hljs-comment">// b === "Hello world" 为 true</span><br>a <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">String</span>; <span class="hljs-comment">// 为 true</span><br>b <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">String</span>; <span class="hljs-comment">// 为 false</span><br><span class="hljs-keyword">typeof</span> a; <span class="hljs-comment">// "object"</span><br><span class="hljs-keyword">typeof</span> b; <span class="hljs-comment">// "string"</span><br></code></pre></td></tr></table></figure><hr><blockquote><h3 id="常用的字符串方法:"><a href="#常用的字符串方法:" class="headerlink" title="常用的字符串方法:"></a>常用的字符串方法:</h3><ul><li><code>concat(value,str)</code>-以value值拼接两个字符串。</li><li><code>endsWith(value,index)/endsWith()</code>-查找字符串是否以value结尾/开头,index为查找的末尾索引+1,返回布尔值。</li><li><code>includes(value)</code>-查找value值,返回布尔值。</li><li><code>indexOf(searchString, position)/lastIndexOf()</code>-查找第一次/最后一次出现searchString的索引,position为查找开始的索引,默认为0。</li><li><code>match()/search()</code>-匹配正则表达式,返回匹配的字符的数组/索引。</li><li><code>replace(value,origin)/replaceAll()</code>-匹配字符串value替换origin,返回替换后的字符串。</li><li><code>slice(start,end)</code>-提取字符串的一部分返回新字符串,不改变原字符串。</li><li><code>split(rule)</code>-按照rule模式将字符串分割成一个数组,返回该数组。</li><li><code>toLowerCase()/toUpperCase()</code>-全部换成小写/大写</li><li><code>trim()</code>-从字符串两端移除空白字符,返回新字符,不修改原来的字符。</li></ul></blockquote><h2 id="Map相关知识"><a href="#Map相关知识" class="headerlink" title="Map相关知识"></a>Map相关知识</h2><p>Map对象保存键值对,并且可以记住键的原始插入顺序,任何值都可以作为键或者值。</p><blockquote><h3 id="Object和Map的区别:"><a href="#Object和Map的区别:" class="headerlink" title="Object和Map的区别:"></a>Object和Map的区别:</h3><table><thead><tr><th align="center">区别</th><th align="center">Map</th><th align="center">Object</th></tr></thead><tbody><tr><td align="center">键的类型</td><td align="center">Map的键可以是任何值</td><td align="center">Object的键必须为字符串或者Symbol</td></tr><tr><td align="center">键的顺序</td><td align="center">Map的对象按照插入的顺序迭代</td><td align="center">Object的排序就很混乱,ES6之后按照属性创建顺序迭代</td></tr><tr><td align="center">迭代</td><td align="center">可迭代对象,可以使用for of</td><td align="center">不可迭代,默认只能用for in</td></tr><tr><td align="center">性能</td><td align="center">在涉及频繁添加和删除键值对的场景中表现更好。</td><td align="center">在涉及频繁添加和删除键值对的场景中表现更好。</td></tr></tbody></table></blockquote><hr><blockquote><h3 id="常用的map方法:"><a href="#常用的map方法:" class="headerlink" title="常用的map方法:"></a>常用的map方法:</h3><ul><li><code>clear()</code>-清除所有元素</li><li><code>delete()</code>-删除指定键的值</li><li><code>forEach()</code>-对每一个键/值进行一次操作</li><li><code>get()</code>-获取指定键的值,一般并对其进行后续处理。</li><li><code>has()</code>-检查指定键是否存在,返回布尔值。</li><li><code>keys()/values()</code>-返回一个迭代器对象,该对象包含了此map中每个元素的键/值</li><li><code>set()</code>-向map中添加一个指定的键值对。</li></ul></blockquote><h2 id="x3D-x3D-和-x3D-x3D-x3D-的区别"><a href="#x3D-x3D-和-x3D-x3D-x3D-的区别" class="headerlink" title="== 和 ===的区别"></a>== 和 ===的区别</h2><p>在使用<code>==</code>时会默认使用隐式转换改变数据类型,<code>===</code>的时候不会。</p><blockquote><h3 id="特殊情况:"><a href="#特殊情况:" class="headerlink" title="特殊情况:"></a>特殊情况:</h3><p>null和undefined只能彼此相等,其他情况均不相等。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-literal">null</span> == <span class="hljs-literal">undefined</span> <span class="hljs-comment">// true</span><br><span class="hljs-literal">null</span> == <span class="hljs-literal">false</span> <span class="hljs-comment">// false</span><br><span class="hljs-literal">undefined</span> == <span class="hljs-literal">false</span> <span class="hljs-comment">//false</span><br></code></pre></td></tr></table></figure></blockquote><h2 id="深拷贝和浅拷贝的区别"><a href="#深拷贝和浅拷贝的区别" class="headerlink" title="深拷贝和浅拷贝的区别"></a>深拷贝和浅拷贝的区别</h2><p>浅拷贝指创建新的数据,如果属性是基本类型,则为其字面量;如果属性为引用类型,拷贝的就是内存地址。即浅拷贝出来的对象还是指向同一个内存地址。</p><blockquote><p>eg.<code>slice()</code>、<code>concat()</code></p></blockquote><p>深拷贝则是开一个新的栈,基本类型的值也是拷贝字面量;但是如果是引用类型,值相同但是会有不同的内存地址。即深拷贝出来的对象不指向同一个内存地址。</p><blockquote><p>eg.<code>JSON.stringify()</code></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//深拷贝</span><br><span class="hljs-keyword">let</span> obj1 = {<span class="hljs-attr">name</span>: <span class="hljs-string">'A'</span>}<br><span class="hljs-keyword">const</span> obj2 = <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">parse</span>(<span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>(obj1));<br>obj1.<span class="hljs-property">name</span> = <span class="hljs-string">'B'</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj2); <span class="hljs-comment">// {name: "A"}</span><br><br><span class="hljs-comment">//浅拷贝</span><br><span class="hljs-keyword">var</span> obj1 = {}<br><span class="hljs-keyword">var</span> obj2 = obj1;<br>obj2.<span class="hljs-property">name</span> = <span class="hljs-string">'B'</span>;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj1.<span class="hljs-property">name</span>); <span class="hljs-comment">// "B"</span><br></code></pre></td></tr></table></figure></blockquote><hr><blockquote><h3 id="手写深拷贝:"><a href="#手写深拷贝:" class="headerlink" title="手写深拷贝:"></a>手写深拷贝:</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">function</span> <span class="hljs-title function_">deepClone</span>(<span class="hljs-params">obj,hash = <span class="hljs-keyword">new</span> <span class="hljs-built_in">WeakMap</span>()</span>){<span class="hljs-comment">//用weakmap是因为垃圾回收策略,避免内存泄漏</span><br> <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> obj !== <span class="hljs-string">'object'</span>||obj === <span class="hljs-literal">null</span>)<span class="hljs-keyword">return</span> obj<span class="hljs-comment">//不是对象直接返回即可,深拷贝是对于对象而言的</span><br> <span class="hljs-keyword">if</span>(obj <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Date</span>)<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>(obj)<br> <span class="hljs-keyword">if</span>(obj <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">RegExp</span>)<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">RegExp</span>(obj)<span class="hljs-comment">//日期、正则对象可以使用他们内置的拷贝构造函数</span><br> <br> <span class="hljs-keyword">if</span>(hash.<span class="hljs-title function_">has</span>(obj))<span class="hljs-keyword">return</span> hash.<span class="hljs-title function_">get</span>(obj)<span class="hljs-comment">//有了就返回</span><br> <span class="hljs-keyword">let</span> cloneObj = <span class="hljs-keyword">new</span> obj.<span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span>)<span class="hljs-comment">//拿某个对象的原型对象构造出来的对象</span><br> hash.<span class="hljs-title function_">set</span>(obj, cloneObj);<span class="hljs-comment">//加到hash中</span><br> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> key <span class="hljs-keyword">in</span> obj) {<span class="hljs-comment">//一层一层向下找</span><br> <span class="hljs-keyword">if</span> (obj.<span class="hljs-title function_">hasOwnProperty</span>(key)) {<span class="hljs-comment">//如果不是继承的就进if</span><br> cloneObj[key] = <span class="hljs-title function_">deepClone</span>(obj[key], hash);<span class="hljs-comment">//递归拿到不是继承的属性的键</span><br> }<br> }<br> <span class="hljs-keyword">return</span> cloneObj;<br>}<br></code></pre></td></tr></table></figure></blockquote><h2 id="闭包"><a href="#闭包" class="headerlink" title="闭包"></a>闭包</h2><p>当我们创建一个函数A中再<strong>创建</strong>一个函数B的时候,B中可以使用在A初始化的数据。这就是闭包,也就是说,闭包可以让你在一个内层函数中访问到其外层函数的作用域。</p><blockquote><h3 id="闭包的使用场景:"><a href="#闭包的使用场景:" class="headerlink" title="闭包的使用场景:"></a>闭包的使用场景:</h3><ul><li><p>创建私有变量:这里使用闭包模拟私有方法。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">var</span> <span class="hljs-title class_">Counter</span> = (<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-keyword">var</span> privateCounter = <span class="hljs-number">0</span>;<br> <span class="hljs-keyword">function</span> <span class="hljs-title function_">changeBy</span>(<span class="hljs-params">val</span>) {<br> privateCounter += val;<br> }<br> <span class="hljs-keyword">return</span> {<br> <span class="hljs-attr">increment</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-title function_">changeBy</span>(<span class="hljs-number">1</span>);<br> },<br> <span class="hljs-attr">decrement</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-title function_">changeBy</span>(-<span class="hljs-number">1</span>);<br> },<br> <span class="hljs-attr">value</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-keyword">return</span> privateCounter;<br> }<br> }<br>})();<br><br><span class="hljs-keyword">var</span> <span class="hljs-title class_">Counter1</span> = <span class="hljs-title function_">makeCounter</span>();<br><span class="hljs-keyword">var</span> <span class="hljs-title class_">Counter2</span> = <span class="hljs-title function_">makeCounter</span>();<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Counter1</span>.<span class="hljs-title function_">value</span>()); <span class="hljs-comment">/* logs 0 */</span><br><span class="hljs-title class_">Counter1</span>.<span class="hljs-title function_">increment</span>();<br><span class="hljs-title class_">Counter1</span>.<span class="hljs-title function_">increment</span>();<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Counter1</span>.<span class="hljs-title function_">value</span>()); <span class="hljs-comment">/* logs 2 */</span><br><span class="hljs-title class_">Counter1</span>.<span class="hljs-title function_">decrement</span>();<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Counter1</span>.<span class="hljs-title function_">value</span>()); <span class="hljs-comment">/* logs 1 */</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Counter2</span>.<span class="hljs-title function_">value</span>()); <span class="hljs-comment">/* logs 0 */</span><br></code></pre></td></tr></table></figure></li><li><p>延长变量的生命周期:本例子中延长了width的生命周期</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">// 假设我们有一个求长方形面积的函数</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">getArea</span>(<span class="hljs-params">width, height</span>) {<br> <span class="hljs-keyword">return</span> width * height<br>}<br><span class="hljs-comment">// 如果我们碰到的长方形的宽老是10</span><br><span class="hljs-keyword">const</span> area1 = <span class="hljs-title function_">getArea</span>(<span class="hljs-number">10</span>, <span class="hljs-number">20</span>)<br><span class="hljs-keyword">const</span> area2 = <span class="hljs-title function_">getArea</span>(<span class="hljs-number">10</span>, <span class="hljs-number">30</span>)<br><span class="hljs-keyword">const</span> area3 = <span class="hljs-title function_">getArea</span>(<span class="hljs-number">10</span>, <span class="hljs-number">40</span>)<br> <br><span class="hljs-comment">// 我们可以使用闭包柯里化这个计算面积的函数(柯里化的意思就是允许把一次填入多参数的函数转化为多次填入参数的函数)</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">getArea</span>(<span class="hljs-params">width</span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-params">height</span> =></span> {<br> <span class="hljs-keyword">return</span> width * height<br> }<br>}<br> <br><span class="hljs-keyword">const</span> getTenWidthArea = <span class="hljs-title function_">getArea</span>(<span class="hljs-number">10</span>)<br><span class="hljs-comment">// 之后碰到宽度为10的长方形就可以这样计算面积</span><br><span class="hljs-keyword">const</span> area1 = <span class="hljs-title function_">getTenWidthArea</span>(<span class="hljs-number">20</span>)<br> <br><span class="hljs-comment">// 而且如果遇到宽度偶尔变化也可以轻松复用</span><br><span class="hljs-keyword">const</span> getTwentyWidthArea = <span class="hljs-title function_">getArea</span>(<span class="hljs-number">20</span>)<br></code></pre></td></tr></table></figure></li></ul></blockquote><h2 id="作用域及作用域链"><a href="#作用域及作用域链" class="headerlink" title="作用域及作用域链"></a>作用域及作用域链</h2><p>作用域决定了代码区块中变量及其他资源的可见性,一般将作用域分为<code>全局作用域</code>、<code>函数作用域</code>、<code>块级作用域</code>,作用域在变量被创建好的时候就确定了,不会随着执行的时候改变。</p><p>作用域链是指你需要调用变量的时候,会先从局部作用域寻找,一直往上直到全局作用域。</p><blockquote><h3 id="全局作用域、函数作用域及块级作用域:"><a href="#全局作用域、函数作用域及块级作用域:" class="headerlink" title="全局作用域、函数作用域及块级作用域:"></a>全局作用域、函数作用域及块级作用域:</h3><p>全局作用域:不在任何函数或者大括号中声明的变量,可以在程序的任何位置访问。</p><p>函数作用域:也叫局部作用域,是在函数内部声明的,不能在函数之外访问(除了闭包)</p><p>块级作用域:ES6中引入了<code>let</code>&<code>const</code>,这两者只能在大括号内访问,大括号外不可以访问。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">var</span> globalValue = <span class="hljs-string">"1"</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">test</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-keyword">var</span> functionValue = <span class="hljs-string">"2"</span><br>}<br><span class="hljs-title function_">test</span>(<span class="hljs-params"></span>)<br>{<br> <span class="hljs-keyword">let</span> blockValue = <span class="hljs-string">"3"</span><br> <span class="hljs-title function_">log</span>(blockValue)<span class="hljs-comment">//"3"</span><br>}<br><br><span class="hljs-title function_">log</span>(globalValue)<span class="hljs-comment">//"1"</span><br><span class="hljs-title function_">log</span>(functionValue)<span class="hljs-comment">// 报错</span><br><span class="hljs-title function_">log</span>(blockValue)<span class="hljs-comment">//报错</span><br></code></pre></td></tr></table></figure></blockquote><h2 id="原型及原型链"><a href="#原型及原型链" class="headerlink" title="原型及原型链"></a>原型及原型链</h2><p>JS中 每一个对象都有一个原型对象,当访问一个对象的属性的时候,JS不仅会在对象上寻找,还会搜索该对象的原型,以及该对象原型的原型(这叫做原型链)直到匹配或者到达原型链的末尾。</p><blockquote><h3 id="什么是对象的属性:"><a href="#什么是对象的属性:" class="headerlink" title="什么是对象的属性:"></a>什么是对象的属性:</h3><p>对象的属性是用来描述对象状态或者特征的,属性可以包含各种各样的数据,可以是基本数据也可以是函数、对象等,每个属性都有一个键值对。</p></blockquote><p>也就是说,这些属性和方法是定义在object的构造函数的<code>prototype</code>而非实例本身。</p><p>实例通过<code>_proto_</code>属性上溯原型链,每个原型都有<code>prototype</code>,而<code>prototype</code>又有<code>constructor</code>属性来指向该原型(<code>constructor</code>主要就是用于指向确认该原型)</p><p><img src="https://static.vue-js.com/60825aa0-725e-11eb-85f6-6fac77c0c9b3.png" alt="60825aa0-725e-11eb-85f6-6fac77c0c9b3.png (721×762) "></p><h2 id="继承"><a href="#继承" class="headerlink" title="继承"></a>继承</h2><p>继承是面向对象中的一个概念,继承可以让子类具有父类的各种属性和方法,不需要再编写相同的代码,并且在子类别继承父类别的同时,可以重新定义某些属性、方法,获得不同的功能。</p><blockquote><h3 id="JS常见的继承方式:"><a href="#JS常见的继承方式:" class="headerlink" title="JS常见的继承方式:"></a>JS常见的继承方式:</h3><ul><li><p>原型链继承(继承方法) </p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//写法一 每一个new Child,创建出来的每一个实例改变父类属性时都会影响到父类。</span><br><span class="hljs-title class_">Child</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Parent</span>();<br><span class="hljs-comment">//写法二 创建原型链继承的现代方法</span><br><span class="hljs-title class_">Child</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span> = <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">create</span>(<span class="hljs-title class_">Parent</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>)<br><span class="hljs-title class_">Child</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">constructor</span> = <span class="hljs-title class_">Child</span><br></code></pre></td></tr></table></figure></li><li><p>构造函数继承(继承属性)</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs JS"><span class="hljs-keyword">function</span> <span class="hljs-title function_">Parent</span>(<span class="hljs-params">name</span>) { <br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">name</span> = name; <span class="hljs-comment">// 设置name属性 </span><br>} <br> <br><span class="hljs-keyword">function</span> <span class="hljs-title function_">Child</span>(<span class="hljs-params">name, age</span>) { <br> <span class="hljs-comment">// 调用父类构造函数,初始化name属性 </span><br> <span class="hljs-title class_">Parent</span>.<span class="hljs-title function_">call</span>(<span class="hljs-variable language_">this</span>, name); <br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">age</span> = age; <span class="hljs-comment">// 设置子类特有的age属性 </span><br>} <br></code></pre></td></tr></table></figure></li></ul></blockquote><h2 id="this"><a href="#this" class="headerlink" title="this"></a>this</h2><p><code>this</code>是函数的一个运行时自动生成的内部对象,只能在函数内使用,指向最后调用它的对象。</p><blockquote><h3 id="绑定规则:"><a href="#绑定规则:" class="headerlink" title="绑定规则:"></a>绑定规则:</h3><p>优先级:new绑定优先级 > 显示绑定优先级 > 隐式绑定优先级 > 默认绑定优先级</p><ul><li><p>默认绑定:全局对象会默认绑定,如果严格模式下,<code>this</code>会绑定到undefined。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-variable language_">window</span>.<span class="hljs-property">name</span> = <span class="hljs-string">'Jenny'</span>;<br><span class="hljs-keyword">function</span> <span class="hljs-title function_">person</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">name</span>;<br>}<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title function_">person</span>()); <span class="hljs-comment">//Jenny,调用函数的对象</span><br></code></pre></td></tr></table></figure></li><li><p>隐式绑定:函数作为对象的某个方法调用,<code>this</code>就指向这个对象</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">var</span> o = {<br> <span class="hljs-attr">a</span>:<span class="hljs-number">10</span>,<br> <span class="hljs-attr">b</span>:{<br> <span class="hljs-attr">a</span>:<span class="hljs-number">7</span>,<br> <span class="hljs-attr">fn</span>:<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">a</span>); <span class="hljs-comment">//undefined</span><br> }<br> }<br>}<br>o.<span class="hljs-property">b</span>.<span class="hljs-title function_">fn</span>();<span class="hljs-comment">//7</span><br><span class="hljs-keyword">var</span> j = o.<span class="hljs-property">b</span>.<span class="hljs-property">fn</span>;<br><span class="hljs-title function_">j</span>();<span class="hljs-comment">//this指向window</span><br></code></pre></td></tr></table></figure></li><li><p>new绑定:如果用<code>new</code>构造函数生成一个实例对象,<code>this</code>指向此对象。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">function</span> <span class="hljs-title function_">test</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">x</span> = <span class="hljs-number">1</span>;<br>}<br><br><span class="hljs-keyword">var</span> obj = <span class="hljs-keyword">new</span> <span class="hljs-title function_">test</span>();<br>obj.<span class="hljs-property">x</span> <span class="hljs-comment">// 1</span><br><span class="hljs-comment">//new过程遇到return一个对象,此时this指向为返回的对象</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">fn</span>(<span class="hljs-params"></span>) <br>{ <br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">user</span> = <span class="hljs-string">'xxx'</span>; <br> <span class="hljs-keyword">return</span> {}; <br>}<br><span class="hljs-keyword">var</span> a = <span class="hljs-keyword">new</span> <span class="hljs-title function_">fn</span>(); <br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(a.<span class="hljs-property">user</span>); <span class="hljs-comment">//undefined</span><br><span class="hljs-comment">//如果返回一个简单类型的时候,则this指向实例对象</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">fn</span>(<span class="hljs-params"></span>) <br>{ <br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">user</span> = <span class="hljs-string">'xxx'</span>; <br> <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;<br>}<br><span class="hljs-keyword">var</span> a = <span class="hljs-keyword">new</span> fn; <br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(a.<span class="hljs-property">user</span>); <span class="hljs-comment">//xxx</span><br><span class="hljs-comment">//注意的是null虽然也是对象,但是此时new仍然指向实例对象</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">fn</span>(<span class="hljs-params"></span>) <br>{ <br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">user</span> = <span class="hljs-string">'xxx'</span>; <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br>}<br><span class="hljs-keyword">var</span> a = <span class="hljs-keyword">new</span> fn; <br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(a.<span class="hljs-property">user</span>); <span class="hljs-comment">//xxx</span><br></code></pre></td></tr></table></figure></li><li><p>显示修改:<code>apply</code> <code>call</code> <code>bind</code>这些方法作用是改变函数的调用方法。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">var</span> x = <span class="hljs-number">0</span>;<br><span class="hljs-keyword">function</span> <span class="hljs-title function_">test</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">x</span>);<br>}<br> <br><span class="hljs-keyword">var</span> obj = {};<br>obj.<span class="hljs-property">x</span> = <span class="hljs-number">1</span>;<br>obj.<span class="hljs-property">m</span> = test;<br>obj.<span class="hljs-property">m</span>.<span class="hljs-title function_">apply</span>(obj) <span class="hljs-comment">// 1</span><br></code></pre></td></tr></table></figure></li></ul></blockquote><p>箭头函数的<code>this</code>在代码书写编译时就已经绑定,会捕获其定义时的词法作用域中的 <code>this</code></p><h2 id="事件与事件模型"><a href="#事件与事件模型" class="headerlink" title="事件与事件模型"></a>事件与事件模型</h2><p>JS中的事件,其实就是浏览器中发生的一种交互操作。</p><p>事件流经历三个阶段:事件捕获阶段(capture phase)、处于目标阶段(target phase)、事件冒泡阶段(bubbling phase)</p><p>事件冒泡是一种从下往上的传播方式,由处于目标阶段的触发节点逐渐向上传播到最上的节点也就是DOM中最高的父节点。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">var</span> button = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">'clickMe'</span>);<br><br>button.<span class="hljs-property">onclick</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'1.Button'</span>);<br>};<br><span class="hljs-variable language_">document</span>.<span class="hljs-property">body</span>.<span class="hljs-property">onclick</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'2.body'</span>);<br>};<br><span class="hljs-variable language_">document</span>.<span class="hljs-property">onclick</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'3.document'</span>);<br>};<br><span class="hljs-variable language_">window</span>.<span class="hljs-property">onclick</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'4.window'</span>);<br>};<br><br><span class="hljs-comment">//1.button</span><br><span class="hljs-comment">//2.body</span><br><span class="hljs-comment">//3.document</span><br><span class="hljs-comment">//4.window</span><br></code></pre></td></tr></table></figure><p>事件模型可以分为三种:原始事件模型(DOM 0级)、标准事件模型(DOM 2级)、IE事件模型。</p><p>一般使用原始事件模型和标准事件模型。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs html">//原始事件模型<br><span class="hljs-tag"><<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"handleClick()"</span>></span>Click me<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br></code></pre></td></tr></table></figure><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//标准事件模型</span><br>element.<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">'click'</span>, handleClick, useCapture);<br></code></pre></td></tr></table></figure><p>区别是原始事件模型简单,但有局限,不支持事件捕获和多个事件处理器;标准事件模型提供更多灵活性和控制。</p><h2 id="typeof与instanceof"><a href="#typeof与instanceof" class="headerlink" title="typeof与instanceof"></a>typeof与instanceof</h2><p><code>typeof</code>操作符返回一个字符串,用于表示未经计算的操作数的类型。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">typeof</span> <span class="hljs-number">1</span> <span class="hljs-comment">// 'number'</span><br><span class="hljs-keyword">typeof</span> <span class="hljs-string">'1'</span> <span class="hljs-comment">// 'string'</span><br><span class="hljs-keyword">typeof</span> <span class="hljs-literal">undefined</span> <span class="hljs-comment">// 'undefined'</span><br><span class="hljs-keyword">typeof</span> <span class="hljs-literal">true</span> <span class="hljs-comment">// 'boolean'</span><br><span class="hljs-keyword">typeof</span> <span class="hljs-title class_">Symbol</span>() <span class="hljs-comment">// 'symbol'</span><br><span class="hljs-keyword">typeof</span> <span class="hljs-literal">null</span> <span class="hljs-comment">// 'object'</span><br><span class="hljs-keyword">typeof</span> [] <span class="hljs-comment">// 'object'</span><br><span class="hljs-keyword">typeof</span> {} <span class="hljs-comment">// 'object'</span><br><span class="hljs-keyword">typeof</span> <span class="hljs-variable language_">console</span> <span class="hljs-comment">// 'object'</span><br><span class="hljs-keyword">typeof</span> <span class="hljs-variable language_">console</span>.<span class="hljs-property">log</span> <span class="hljs-comment">// 'function'</span><br></code></pre></td></tr></table></figure><p><code>instanceof</code> 运算符用于检测构造函数的 <code>prototype</code> 属性是否出现在某个实例对象的原型链上,返回布尔值。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">// 定义构建函数</span><br><span class="hljs-keyword">let</span> <span class="hljs-title class_">Car</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {}<br><span class="hljs-keyword">let</span> benz = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Car</span>()<br>benz <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Car</span> <span class="hljs-comment">// true</span><br><span class="hljs-keyword">let</span> car = <span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>(<span class="hljs-string">'xxx'</span>)<br>car <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">String</span> <span class="hljs-comment">// true</span><br><span class="hljs-keyword">let</span> str = <span class="hljs-string">'xxx'</span><br>str <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">String</span> <span class="hljs-comment">// false</span><br></code></pre></td></tr></table></figure><blockquote><h3 id="手写instanceof:"><a href="#手写instanceof:" class="headerlink" title="手写instanceof:"></a>手写instanceof:</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">function</span> <span class="hljs-title function_">myInstanceOf</span>(<span class="hljs-params">left,right</span>){<br> <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> left !== <span class="hljs-string">'object'</span>||<span class="hljs-keyword">typeof</span> left === <span class="hljs-literal">null</span>)<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span><br> <span class="hljs-keyword">let</span> proto = <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">getPrototypeOf</span>(left)<br> <span class="hljs-keyword">while</span>(<span class="hljs-literal">true</span>){<br> <span class="hljs-keyword">if</span>(proto === <span class="hljs-literal">null</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<span class="hljs-comment">//防止不是使用构造函数创建的实例</span><br> <span class="hljs-keyword">if</span>(proto === right.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>)<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span><br> proto = <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">getPrototypeOf</span>(proto)<br>}<br>}<br></code></pre></td></tr></table></figure></blockquote><h2 id="事件代理"><a href="#事件代理" class="headerlink" title="事件代理"></a>事件代理</h2><p>事件委托,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,而不是目标元素。</p><p>如果我们有一个列表,列表之中有大量的列表项,我们需要在点击列表项的时候响应一个事件,如果给每个列表项一一都绑定一个函数,那对于内存消耗是非常大的,这时候就可以事件委托,把点击事件绑定在父级元素<code>ul</code>上面,然后执行事件的时候再去匹配目标元素。</p><h2 id="New"><a href="#New" class="headerlink" title="New"></a>New</h2><p>我们使用new将一个给定的构造函数创建一个实例对象。new做了如下事情:</p><ul><li>创建一个新的对象</li><li>将对象与构造函数用原型链连起来</li><li>将构造函数的this指向对象(改变this指向的方法之一)</li></ul><blockquote><h3 id="手写new:"><a href="#手写new:" class="headerlink" title="手写new:"></a>手写new:</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">function</span> <span class="hljs-title function_">mynew</span>(<span class="hljs-params">Fun,...args</span>){<br><span class="hljs-keyword">const</span> obj = {}<br> obj.<span class="hljs-property">_proto_</span> = <span class="hljs-title class_">Fun</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span><br> <span class="hljs-keyword">let</span> result = <span class="hljs-title class_">Fun</span>.<span class="hljs-title function_">apply</span>(obj,args)<br> <span class="hljs-keyword">return</span> result <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Object</span>?<span class="hljs-attr">result</span>:obj;<br>}<br></code></pre></td></tr></table></figure></blockquote><h2 id="事件循环"><a href="#事件循环" class="headerlink" title="事件循环"></a>事件循环</h2><p>JS中所有任务都可以分为同步任务和异步任务。其中异步任务还可以分为微任务和宏任务。</p><blockquote><h3 id="微任务和宏任务:"><a href="#微任务和宏任务:" class="headerlink" title="微任务和宏任务:"></a>微任务和宏任务:</h3><ul><li>微任务:一个需要异步执行的函数,执行时机是在当前主函数执行结束后,宏任务结束之前。例如:Promise.then、Process.nextTick</li><li>宏任务:常见的宏任务有:setTimeout/setInterval、I/O</li></ul></blockquote><hr><blockquote><h3 id="async和await:"><a href="#async和await:" class="headerlink" title="async和await:"></a>async和await:</h3><p>async函数会返回一个promise对象,await会将其后的代码化为微任务。</p></blockquote><h2 id="防抖和节流"><a href="#防抖和节流" class="headerlink" title="防抖和节流"></a>防抖和节流</h2><h1 id="杂项"><a href="#杂项" class="headerlink" title="杂项"></a>杂项</h1><h2 id="Hash算法"><a href="#Hash算法" class="headerlink" title="Hash算法"></a>Hash算法</h2><p>hash(哈希)算法是把任意长度的输入,通过算法变换成固定长度的输出。</p><blockquote><p> eg.<a href="https://leetcode.cn/problems/two-sum/description/?envType=study-plan-v2&envId=top-100-liked">两数之和</a></p></blockquote><h1 id="实际面试环节"><a href="#实际面试环节" class="headerlink" title="实际面试环节"></a>实际面试环节</h1><h2 id="10-15海康威视"><a href="#10-15海康威视" class="headerlink" title="10.15海康威视"></a>10.15海康威视</h2><ul><li><p>你的上一段实习有什么亮点/难点?</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs markdown">原答:需要对给过来的一些数据进行处理。<br><br>修正:当时作为初学者接到的任务都不是很难,主要遇到的困难有使用Element Plus样式穿刺、组件间传值这些问题。<br></code></pre></td></tr></table></figure></li><li><p>JS中常用的数据结构类型有哪些?</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs markdown">原答:7种,number,undefined,string,null,boolean,symbol,其他的类型统称object,object可能包含对象、数组、函数之类的。<br><br>修正:JS中有六种基本的数据类型,分别是number、string、boolean还有undefined、null和symbol。除此之外还有一个复杂数据类型object,它包含了对象、数组和函数等,这些对象可以用来构建更复杂的数据结构,例如链表、树等。<br></code></pre></td></tr></table></figure></li><li><p>JS怎么处理大整形类型?</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs markdown">原答:一般是用bigint,对数据转化成大整形类型之后如果需要加加减减的话就要加n,比如加一就是加一n<br><br>修正:在JS中处理大整数,可以使用BigInt类型,它允许你安全地表示和操作超出Number类型安全范围的大整数。使用BigInt时,只需要在数值后面加上n或者用BigInt()函数来创建。进行算数运算时,必须所有操作数都是BigInt类型,BigInt与Number不兼容。<br></code></pre></td></tr></table></figure></li><li><p>JS的Map和对象有什么区别?</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs markdown">原答:Map和对象的一些方法属性可能不同,比如has、get之类的。<br><br>修正:首先Map的键可以是任意类型的,对象的键在访问的时候总是被当作字符串处理。迭代顺序不同,对象是按照属性创建时间迭代,Map是按照添加到map的顺序迭代。对象没有内置方法取得键值,Map有keys,values之类的。数据规模小时使用对象,数据规模大时使用map,因为map是为了快速查找而优化的。对象有原型链,Map没有原型链。<br></code></pre></td></tr></table></figure></li><li><p>怎么获取对象的属性值?返回一个数组,数组是对象的所有值怎么写?</p><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs pgsql">原答:直接用键获取就可以了,用<span class="hljs-keyword">Object</span>.<span class="hljs-keyword">values</span>()即可返回数组。<br><br>修正:可以使用<span class="hljs-keyword">Object</span>的静态方法<span class="hljs-keyword">values</span>,也可以使用forin循环中间包一个obj.hasOwnProperty(key)用于确保该键是此对象的,而不是继承下来的。<br></code></pre></td></tr></table></figure></li><li><p>对象可以直接用for of循环拿这些值吗?</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs rust">原答:可以,直接用<span class="hljs-keyword">for</span> <span class="hljs-title class_">of</span>应该就可以拿到。<span class="hljs-comment">//你知道什么是可迭代对象吗?对象还可以用for of拿这些值吗?</span><br><br>修正:不可以,<span class="hljs-keyword">for</span> <span class="hljs-title class_">of</span>是用于遍历可迭代对象的每个元素,例如数组 字符串 Map Set。<span class="hljs-keyword">for</span> <span class="hljs-title class_">in</span>用于遍历一个对象的所有可枚举的属性,包括其原型链上继承的。<br></code></pre></td></tr></table></figure></li><li><p>讲一下原型链吧</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs markdown">原答:意思是说每一个对象,每一个对象构建的时候需要用构造函数去构造原型。每一个对象都有一个prototype指向它的属性,里面还有一个constructor指向他自己,如果我需要用一个构造函数去构造一个新的对象的话,新的对象也会有一个<span class="hljs-emphasis">_proto_</span>指向原来的构造函数,如果想要获取一开始的构造函数的话,可以用原型链溯源往上找。<br><br>修正:原型链是一个用于实现继承的机制,每个对象都有一个内部属性,叫做prototype,这个内部属性引用了另一个对象,称为该对象的原型,代码中一般用getPrototypeOf去获取。这个对象的原型又有一个原型,这样一直往上就是原型链。如果想要访问一个对象的属性时,该对象本身没有这个属性,JS会沿着原型链网上找直到找到或者达到末端。<br></code></pre></td></tr></table></figure></li><li><p>你有一个实例,怎么通过这个实例拿到他的构造函数?</p><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs awk">原答:可以通过循环访问_proto_去找他的原型,如果寻找到的原型的prototype和实例的相同,那就说明这是他的构造函数。<span class="hljs-regexp">//</span>不对,八股文背得太浅了,没有理解本质<br><br>修正:可以使用对象.constructor获取其构造函数,但是这个值其实可以被覆盖的。如果需要更稳健的方法,那可能得创建实例的时候就保存这个引用关系。<br></code></pre></td></tr></table></figure></li><li><p>什么是构造函数,什么是原型对象?</p><figure class="highlight haxe"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs haxe">原答:构造函数就是用于构造对象的函数,原型对象就是你要创建一个实例的一个对象,比如我<span class="hljs-keyword">new</span> <span class="hljs-type">Person</span>(),Person就是他的原型对象。<br><br>修正:构造函数是用于创建函数的函数,当用<span class="hljs-keyword">new</span><span class="hljs-type"></span>关键字调用了一个函数时,这个函数就成为了一个构造函数。构造函数会创建一个新的对象,这个对象会继承构造函数prototype的属性和方法。原型对象是指某个对象中prototype所指向的对象,每个对象都有一个对象原型,该对象从其对象原型中继承相关的属性和方法。<br></code></pre></td></tr></table></figure></li><li><p>在Vue场景下,让你封装一个Vue组件,组件实现一个登录表单界面,一个name一个password,要求创建一个子组件给别人用,别人通过v-model传进来,你的表单里也是有一个name和password,如果后续你的表单扩了,后续别人也是通过v-model传,你的这个自定义组件的v-model怎么实现?</p><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs awk">原答:不太理解 <br><span class="hljs-regexp">//</span>那你v-model怎么用的? <br>原答:绑定我所需要的一些input之类的 <br><span class="hljs-regexp">//</span>那自己写的组件不可以用v-model吗? <br>原答:直接赋值不就行了吗?<br><span class="hljs-regexp">//</span>什么是v-model<br>原答:是用vue的时候写在盒子里的用于双向绑定的。<br><span class="hljs-regexp">//</span>那如果我绑定在你自定义的属性上面呢?v-model是为了解决什么问题?<br>原答:是为了解决视图到模型的问题吧<br><br>修正:可以使用一个对象来作为v-model的值,并且为每一个属性创建一个input事件,这样在调用这个组件的时候外面只管传一个对象即可。<br><br>修正:v-model是用于表单输入和应用状态之间创建数据双向绑定,对于自定义组件,可以使用defineModel来简化v-model,接收传入的值和及时返回改变的值。<br></code></pre></td></tr></table></figure></li></ul><h2 id="10-16云合智网"><a href="#10-16云合智网" class="headerlink" title="10.16云合智网"></a>10.16云合智网</h2><ul><li><p>ES6有接触过吗,用过里面的哪些东西呢?</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript">原答:用过<span class="hljs-title class_">Map</span>之类的,和箭头函数。<br><br>修正:使用过箭头函数、模板字符串、解构赋值、<span class="hljs-title class_">Promise</span>异步、<span class="hljs-keyword">let</span>和<span class="hljs-keyword">const</span>、<span class="hljs-title class_">Map</span>等。<br></code></pre></td></tr></table></figure></li><li><p>能说一下箭头函数有哪些优势吗?</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs kotlin">原答:箭头函数和普通函数的区别是写法不同,箭头函数的<span class="hljs-keyword">this</span>指向它本身,普通函数的<span class="hljs-keyword">this</span>按照JS规定指向,普通函数可以用new去构造,箭头函数不可以。<br><br>修正:箭头函数的出现让函数的书写变得很简洁,除此之外还解决了<span class="hljs-keyword">this</span>执行环境所造成的一些问题,比如匿名函数和setTimeout的<span class="hljs-keyword">this</span>指向问题。<br></code></pre></td></tr></table></figure></li><li><p>Map的键可以有哪些类型?</p><figure class="highlight arcade"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs arcade">原答:<span class="hljs-built_in">Map</span>的键可以是任何类型,如果是对象就不可以,对象的键只能被读为字符串。<br><br>(无修正,答得挺好的,下次加油)<br></code></pre></td></tr></table></figure></li><li><p>call、apply和bind的区别?</p><figure class="highlight gradle"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs gradle">原答:这三者都是用于改变<span class="hljs-keyword">this</span>的指向,<span class="hljs-keyword">call</span>传入两个值,第一个值是指向的对象,第二个值传入一个参数。apply第二个值是传入的数组,然后bind就是直接返回指向的对象。<br><br>修正:这三个函数都用于改变<span class="hljs-keyword">this</span>指向,他们三个都是函数对象的静态方法,当一个函数调用<span class="hljs-keyword">call</span>的时候,会把函数中的<span class="hljs-keyword">this</span>指向改为传入的第一个对象值,还能接受一系列参数,这些参数会传递给函数。apply的用法和<span class="hljs-keyword">call</span>差不多,但是他不再接受一系列参数而是一个数组。bind和<span class="hljs-keyword">call</span>用法一样,但是返回一个新函数可以稍后调用。<br></code></pre></td></tr></table></figure></li><li><p>有没有了解过let、const和var有什么区别?</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs csharp">原答:<span class="hljs-keyword">let</span>和<span class="hljs-keyword">const</span>是ES6新增的特性,是块级元素;<span class="hljs-keyword">var</span>一般作用域全局变量。<span class="hljs-keyword">let</span>的值是可变的,<span class="hljs-keyword">const</span>的值是不可变的,如果你想要试图改变它的话会报错。<span class="hljs-comment">//那如果const定义一个对象,那么我们可以改变这个对象里属性的值吗?</span><br>原答:可以的<br><br>修正:<span class="hljs-keyword">var</span>变量具有函数作用域,但是<span class="hljs-keyword">let</span>和<span class="hljs-keyword">const</span>是块级作用域;<span class="hljs-keyword">let</span>和<span class="hljs-keyword">var</span>可以被重新赋值,<span class="hljs-keyword">const</span>不能被重新赋值,但这不代表它指向的引用类型比如对象或数组内容不能改变。当<span class="hljs-keyword">var</span>在全局作用域下声明变量的时候,这个变量会变成全局对象的属性,<span class="hljs-keyword">let</span>和<span class="hljs-keyword">const</span>就不会。<br></code></pre></td></tr></table></figure></li><li><p>你了解过哪些进行深拷贝的方法?</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript">原答:getPrototypeOf,通过获取某个对象的原型的属性和方法来进行深拷贝。<span class="hljs-comment">//还有别的吗</span><br><br>修正:<span class="hljs-title class_">JSON</span>.<span class="hljs-property">stringify</span>+<span class="hljs-title class_">JSON</span>.<span class="hljs-property">parse</span>序列化加反序列化可以深拷贝,但是这种方法不可以复制函数、<span class="hljs-literal">undefined</span>和循环引用。有些对象比如日期对象 正则对象可以使用他们的拷贝构造函数来进行深拷贝。还有一种方法就是手写递归拷贝。(一定要会手写)<br></code></pre></td></tr></table></figure></li><li><p>有没有了解过闭包?</p><figure class="highlight less"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs less">原答:假如在函数<span class="hljs-selector-tag">a</span>中定义了一个函数<span class="hljs-selector-tag">b</span>,<span class="hljs-selector-tag">b</span>中可以用到<span class="hljs-selector-tag">a</span>定义的量。<span class="hljs-comment">//什么时候使用闭包?</span><br>原答:用于构建私有变量,用于...说不出,可以举个例子。...(但是举错了,把延长变量存在时间的例子举成了构建私有变量的了。)<br><br>修正:(答得挺好的,把例子举完整即可)<br></code></pre></td></tr></table></figure></li><li><p>有没有用过splice这个函数?</p><figure class="highlight arcade"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs arcade">原答:用过,<span class="hljs-built_in">splice</span>对数组进行操作,第一个值是指要操作的索引,第二个值是要删除元素的数量,<span class="hljs-built_in">splice</span>会从该索引后删除指定数量的元素,第三个值是值删除后在这个位置添加的数组。<br><br>(无修正,答得挺好的,下次加油)<br></code></pre></td></tr></table></figure></li><li><p>有没有了解过事件冒泡?</p><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs arduino">原答:在DOM中有三个阶段,第一个是啥来着,会去找那个事件,从最高的window往下找,一直找到那个事件,然后进入处于目标状态,比如click获得这个事件的状态,然后再往上冒泡,再从最小的盒子再冒泡到全局变量。<br><br>修正:当在DOM树中触发了一个事件,比如点击或键盘输入,这个事件会经历三个阶段:分别是事件捕获、目标阶段、事件冒泡。事件捕获会从文档的根节点开始一直传播到目标元素本身。然后就到了目标阶段,这里就是事件实际发生的地方。然后就从目标元素开始向上冒泡,一直冒泡到根元素,我们可以在目标元素以上的祖先元素设置事件监听器来响应事件。<br></code></pre></td></tr></table></figure></li><li><p>你用过HTML5吗,用过里面什么东西?</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript">原答:...(不确定是不是<span class="hljs-title class_">HTML5</span>的)<br><br>修正:用过header、footer等语义元素,有助于搜索引擎优化。用过<span class="hljs-variable constant_">H5</span>的一些新表单类型,比如<span class="hljs-keyword">type</span>=email、url、<span class="hljs-built_in">number</span>。用过video元素嵌入视频。用过canvas绘制图形。用过<span class="hljs-variable language_">localStorage</span>和<span class="hljs-variable language_">sessionStorage</span>存储数据。<br></code></pre></td></tr></table></figure></li><li><p>有接触过HTML5的websocket吗?</p><figure class="highlight livecodeserver"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs livecodeserver">原答:我拿它和平时我们用的一些协议来对比吧,比如我们平时用的是Http、Https,然后用<span class="hljs-built_in">get</span>、<span class="hljs-built_in">post</span>传请求,这种只能是一次过一次回这样之类的,但是websocket是进行一个长线链接,比如说我要做一个聊天网站,我在这边发,另一台电脑也会马上同步信息过去,这就是平时websocket需要用到的一个场景。<br><br>修正:websocket提供了一种在单个TCP连接上进行全双工通信的方法,这就意味着服务器和客户端可以同时发送和接收数据,这和传统的<span class="hljs-keyword">http</span>响应模式不同,<span class="hljs-keyword">http</span>通常只支持客户端到服务器的单向通信。<br></code></pre></td></tr></table></figure></li><li><p>你对Http协议了解得多吗?</p><figure class="highlight livecodeserver"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs livecodeserver">原答:只了解一点<span class="hljs-comment">点//现在最新的版本是多少?</span><br>原答:http2吧好像到<span class="hljs-number">3</span>了。<br><br>修正:<span class="hljs-keyword">http</span>叫做超文本传输协议,是实现网络通信的一种规范,是万维网的数据通信的基础。最新的版本是<span class="hljs-number">2022</span>年刚更新的http3,添加的一些特性包括改用基于UDP的QUIC协议作为传输层协议,取代了传统的TCP协议。quick UDP <span class="hljs-keyword">internet</span> connections整合了TCP的可靠性和UDP的低延迟性,同时还提供TLS加密。QUIC还允许IP地址变化的情况下保持连接状态,提供了更高效的重传机制,能够更快地检测和回复丢包。<br></code></pre></td></tr></table></figure></li><li><p>有了解过https和http的区别吗?</p><figure class="highlight livecodeserver"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs livecodeserver">原答:<span class="hljs-keyword">https</span>简单来说就是<span class="hljs-keyword">http</span>+TLS/SSL 因为<span class="hljs-keyword">http</span>本身是不安全的,<span class="hljs-keyword">https</span>相当于在<span class="hljs-keyword">http</span>上进行了一个加密,需要在网站上获取证书啊,去进行一个传来的密文的解密。<br><br>修正:<span class="hljs-keyword">http</span>的信息传输是明文进行的,没有进行加密处理。<span class="hljs-keyword">https</span>在<span class="hljs-keyword">http</span>的基础上加入了SSL/TLS协议,连接的时候需要进行额外的握手过程,保证一定安全但也会消耗一些性能。<span class="hljs-keyword">http</span>的端口默认使用<span class="hljs-number">80</span>,<span class="hljs-keyword">https</span>的端口默认使用<span class="hljs-number">443</span>。<span class="hljs-keyword">http</span>不需要申请证书,<span class="hljs-keyword">https</span>需要。搜索引擎策略会给<span class="hljs-keyword">https</span>的网站更高的曝光度。<br></code></pre></td></tr></table></figure></li><li><p>有没有了解过https加密用的是什么算法呢?</p><figure class="highlight arcade"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs arcade">原答:没有<br><br>修正:主要用非对称加密算法例如公钥私钥、对称加密算法例如三重数据加密算法、<span class="hljs-built_in">hash</span>算法去加密。<br></code></pre></td></tr></table></figure></li><li><p>有了解过http请求方法有哪些吗?</p><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs pgsql">原答:常用的<span class="hljs-keyword">get</span> post,不常用的push <span class="hljs-keyword">delete</span>之类的<br><br>修正:<span class="hljs-keyword">GET</span>方法用于从服务器获取数据,POST方法用于向服务器发送数据,PUT用于向服务器发送数据用以替换内容,<span class="hljs-keyword">DELETE</span>用于请求服务器删除资源,<span class="hljs-keyword">OPTIONS</span>用于返回服务器支持的HTTP方法及查看服务器性能,TRACE方法用于回显服务器收到的请求,用于调试。<br></code></pre></td></tr></table></figure></li><li><p>有了解过get post有什么区别吗?</p><figure class="highlight stata"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs stata">原答:getpost平时我们用的时候都是要有请求头的,然后<span class="hljs-keyword">post</span>是可以传一个请求内容的。<br><br>修正:GET主要是向服务器获取数据,在url明文传递内容,不安全,且只能传输ASCII字符。<span class="hljs-keyword">POST</span>主要是向服务器提交数据,在请求体中传递内容,可以传输多种数据类型,比如文本,二进制文件。<br></code></pre></td></tr></table></figure></li><li><p>有了解过常见的http响应码有哪些吗?</p><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs pgsql">原答:<span class="hljs-number">200</span>开头的就是服务正常,<span class="hljs-number">300</span>开头没怎么见过,<span class="hljs-number">400</span>开头比如<span class="hljs-number">404</span> <span class="hljs-number">405</span><span class="hljs-keyword">Method</span> <span class="hljs-keyword">Not</span> Allow这种一般是前端路由这边的一些问题,<span class="hljs-number">500</span>开头一般是服务器那边的问题。<br><br>修正:<span class="hljs-number">100</span>是服务器已经接收到请求的一部分;<span class="hljs-number">2</span>xx是成功响应码,例如<span class="hljs-number">200</span>是成功;<span class="hljs-number">3</span>xx是重定向响应码,例如<span class="hljs-number">301</span>表示请求的资源已经被移动到新的url,会返回新的url;<span class="hljs-number">4</span>xx是客户端错误,例如<span class="hljs-number">400</span>bad request错误的参数或地址,服务器理解不了,<span class="hljs-number">403</span>forbidden服务器拒绝请求,<span class="hljs-number">404</span><span class="hljs-keyword">not</span> <span class="hljs-built_in">found</span>找不到资源,<span class="hljs-number">405</span><span class="hljs-keyword">method</span> <span class="hljs-keyword">not</span> allow请求方法服务器不允许;<span class="hljs-number">5</span>xx是服务器错误,例如<span class="hljs-number">500</span>是服务器错误,<span class="hljs-number">503</span>是服务器超载。<br></code></pre></td></tr></table></figure></li><li><p>有没有了解Vue中computed和watch有什么区别?</p><figure class="highlight angelscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs angelscript">原答:计算属性不太了解,watch是用于监听<span class="hljs-built_in">ref</span>属性的改变,如果改变的话就会执行后续的相应函数。<br><br>修正:computed属性是基于其他其他的响应式数据动态计算并返回一个新的值,有缓存功能,只有当其依赖的数据发生变化时,才会重新计算,通常用于一个属性受到多个属性影响。watch属性是监听某个响应式属性,没有缓存功能,一旦监听的值改变就会发生回调,通常用于一个属性影响多个属性。<br></code></pre></td></tr></table></figure></li><li><p>写v-for的时候一般会加一个key,为什么?</p><figure class="highlight lsl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs lsl">原答:<span class="hljs-type">key</span>是用于和v-for一起去遍历盒子的<br><br>修正:<span class="hljs-type">key</span>作为唯一标识,可以帮助vue快速定位到需要更新的DOM元素,提高渲染效率。同时还需要选择稳定的<span class="hljs-type">key</span>去保持每个列表值与其对应的组件实例的稳定关系。<br></code></pre></td></tr></table></figure></li><li><p>如果你的vue项目中遇到兄弟组件之间的通信,你会用什么方法呢?</p><figure class="highlight lasso"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs lasso">原答:用一些相关的插件比如pinia,可以让父传子props再用子传父emit<br><br>修正:使用父传子props再用子传父$emit,如果是祖先组件传给后代组件可以用<span class="hljs-keyword">provide</span>和inject,如果是那种没什么关系的组件传值的话,一般用全局总线库或者pinia。<br></code></pre></td></tr></table></figure></li><li><p>有部署过项目嘛,用什么Web容器呢?</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs">原答:直接把文件传到服务器中,然后用nginx去部署的<br><br>修正:使用Nginx部署。(常见的还有tomcat,但是没用过就不强答了。)<br></code></pre></td></tr></table></figure></li><li><p>那你改过nginx的配置嘛?</p><figure class="highlight glsl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs glsl">原答:改过端口号和<span class="hljs-keyword">index</span>页面和<span class="hljs-keyword">location</span>指向我的文件夹。<br><br>修正:监听端口、<span class="hljs-keyword">location</span>块、SSL/TLS证书和密钥。<br></code></pre></td></tr></table></figure></li><li><p>平常有接触linux?</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs">原答:接触得少<br><br>(没什么好说的,不是一下子能提升的)<br></code></pre></td></tr></table></figure></li><li><p>听说过docker容器嘛?</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs">原答:听说过,相当于我这边写好了,然后用docker把我这边的环境什么的打包给别人。<br><br>修正:Docker容器中包含应用程序所需要的一切运行条件,包括代码、系统工具和库等,它可以解决同一个代码放我这里能跑放别人电脑跑不了的情况。<br></code></pre></td></tr></table></figure></li><li><p>有没有用过集成持续部署的软件,比如说Jenkins</p><figure class="highlight mipsasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs mipsasm">原答:没有用过<br><br>修正:用过Gitlab,知道<span class="hljs-keyword">jenkins,Gitlab可以将gitlab仓库的代码持续集成和部署。 </span><br></code></pre></td></tr></table></figure></li><li><p>平常CSS写得多嘛,相对定位和绝对定位解释一下</p><figure class="highlight scss"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs scss">原答:一般是给父盒子相对定位,然后想要使用绝对定位,需要给父元素设置相对定位才能使用绝对定位,绝对定位是相对于父元素的。<br><br>修正:相对定位的通过<span class="hljs-attribute">position</span> relative设置,设置之后改动偏移量盒子会偏移,但是它还是占据原来的位置。设置绝对定位是<span class="hljs-attribute">position</span> absolute,需要给他父元素设置相对定位,绝对定位就会完全脱离文档流,不再占据原来的空间。根据偏移量移动。<br></code></pre></td></tr></table></figure></li><li><p>用过flex布局嘛,flex布局他的容器上有哪些属性呢?</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs css">原答:比如说常用的<span class="hljs-attribute">justify-content</span>、align-item。<span class="hljs-attribute">flex-wrap</span>可以对子元素进行换行处理。<br><br>修正:用过,比如<span class="hljs-attribute">flex-direction</span>决定主轴方向,<span class="hljs-attribute">flex-wrap</span>决定子元素是否换行,<span class="hljs-attribute">justify-content</span>决定主轴的对齐方式,<span class="hljs-attribute">align-items</span>决定和主轴交叉的那个轴的对齐方式。<br></code></pre></td></tr></table></figure></li><li><p>算法题:100~999的水仙花数</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//原答:</span><br><span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">100</span>; i < <span class="hljs-number">999</span>; i++){<br> <span class="hljs-keyword">let</span> sum = <span class="hljs-number">0</span><br> <span class="hljs-keyword">let</span> temp = i<br> <span class="hljs-keyword">while</span> (temp > <span class="hljs-number">0</span>) {<br> sum += (temp % <span class="hljs-number">10</span>) ** <span class="hljs-number">3</span><br> temp = <span class="hljs-built_in">parseInt</span>(temp/<span class="hljs-number">10</span>)<br> }<br> <span class="hljs-keyword">if</span>(sum === i)<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(i);<br>}<br><br><span class="hljs-comment">//(挺好的)</span><br></code></pre></td></tr></table></figure></li></ul>]]></content>
<summary type="html">面试问题集合</summary>
<category term="随笔" scheme="http://example.com/categories/%E9%9A%8F%E7%AC%94/"/>
<category term="😶🌫️" scheme="http://example.com/tags/%F0%9F%98%B6%E2%80%8D%F0%9F%8C%AB%EF%B8%8F/"/>
</entry>
<entry>
<title>Eventstorm</title>
<link href="http://example.com/2024/07/01/Eventstorm/"/>
<id>http://example.com/2024/07/01/Eventstorm/</id>
<published>2024-07-01T04:11:49.000Z</published>
<updated>2024-07-01T07:30:23.237Z</updated>
<content type="html"><![CDATA[<h1 id="简介及概念"><a href="#简介及概念" class="headerlink" title="简介及概念"></a>简介及概念</h1><p>什么是事件风暴?</p><p>事件风暴是一场发现事件模型的头脑风暴会议,通过领域专家、产品经理和技术人员共同头碰头的群策群力,以事件模型为主要线索,发现业务系统中发生的代表重要事实的重要事件。</p><p>事件风暴是Alberto Brandolini的心血结晶,它是Gamestorming和领域驱动设计(DDD)原则的综合学习实践。</p><blockquote><p>领域驱动设计(DDD,Domain-Driven Design)是一种通过将实现连接到持续进化的模型来满足复杂需求的软件开发方法。</p><p>领域驱动设计的前提是:</p><ul><li>把项目的主要重点放在核心领域(core domain)和域逻辑。</li><li>把复杂的设计放在有界域(bounded context)的模型上。</li><li>发起一个创造性的合作之间的技术和域界专家以迭代地完善的概念模式,解决特定领域的问题。</li></ul></blockquote><p>事件风暴催化并加速小组学习,通常在几小时或几天内实现更传统的建模技术从未做过的事情。</p><p>事件风暴使用简单的便利贴来实现。</p><h1 id="特点及用处"><a href="#特点及用处" class="headerlink" title="特点及用处"></a>特点及用处</h1><h2 id="快速"><a href="#快速" class="headerlink" title="快速"></a>快速</h2><p>事件风暴能够很快的(通常只需几天或几个小时)搭建出业务流程的模型。</p><h2 id="清晰"><a href="#清晰" class="headerlink" title="清晰"></a>清晰</h2><p>通过多角色对于业务流程的完善,事件风暴使得整个模型显得尤为清晰,在我看来,他更像是把业务专注于“业务”本身。</p><p>我为什么这么说呢 -> 如果我们正常对模型进行搭建的时候,可能是靠自己(或者是某个部门)对整个业务进行模拟:我需要什么,我要做什么。虽然这是我们能够做到最好的情况了,但是因为业务不止需要一个部门去实现,这样做往往会导致我们一开始看起来很合适的的某个部分,在别的人眼里显得非常的怪异。</p><p>这就催生出了事件风暴,对于业务模型中的事件,不同的人有不同的答案。</p><h2 id="简单"><a href="#简单" class="headerlink" title="简单"></a>简单</h2><p>事件风暴具有简单的特性,对于没有编程背景的人,只需一点点的逻辑性就可以参与进来,这对于业务开发是十分高效且合理的。</p><h1 id="核心概念"><a href="#核心概念" class="headerlink" title="核心概念"></a>核心概念</h1><h2 id="领域事件-Event"><a href="#领域事件-Event" class="headerlink" title="领域事件 Event"></a>领域事件 Event</h2><ul><li>指正在探索的领域的相关事件,命名需要代表深刻的业务领域含义。</li></ul><h2 id="参与者-Actor"><a href="#参与者-Actor" class="headerlink" title="参与者 Actor"></a>参与者 Actor</h2><ul><li>指涉及领域事件的的人员,一组人、一个团队或者某个人。(也可以说是对应探索领域的用户)</li></ul><h2 id="外部系统-External-System"><a href="#外部系统-External-System" class="headerlink" title="外部系统 External System"></a>外部系统 External System</h2><ul><li>可部署的IT系统,我认为是用于补充actor,比如事件的触发可能是通过外部第三方系统产生。</li></ul><h2 id="策略-Policy"><a href="#策略-Policy" class="headerlink" title="策略 Policy"></a>策略 Policy</h2><ul><li>根据业务约束或者是规则自动或手动触发。</li></ul><h2 id="命令-Command"><a href="#命令-Command" class="headerlink" title="命令 Command"></a>命令 Command</h2><ul><li>代表行动、意图,指一个触发器。</li></ul><h2 id="读模型-Read-Model"><a href="#读模型-Read-Model" class="headerlink" title="读模型 Read Model"></a>读模型 Read Model</h2><ul><li>参与者需要某些信息做出决策,通过读模型来获取这些信息。</li></ul><h2 id="聚合-Aggregate"><a href="#聚合-Aggregate" class="headerlink" title="聚合 Aggregate"></a>聚合 Aggregate</h2><ul><li>一个对象群体、一类对象的总称。</li></ul><h1 id="流程"><a href="#流程" class="headerlink" title="流程"></a>流程</h1><h2 id="事件风暴会议开始"><a href="#事件风暴会议开始" class="headerlink" title="事件风暴会议开始"></a>事件风暴会议开始</h2><p>在主持人的指导下,与业务专家开始梳理当前的业务中有哪些领域事件。(即已经发生需要保存下来的那些事实)。</p><p>只有先找到发生的事实,将其标记为领域事件,才能发现这些事实涉及哪些对象,对象之间的结构边界才能得到划分,而划分了边界的对象才可能是DDD中的限界上下文。</p><p>针对每一个领域事件,项目组成员围绕它进行业务分析,增加各种命令与事件,进行思考与之相关的资源、外部系统与时间。</p><h2 id="按照时间线组织事件"><a href="#按照时间线组织事件" class="headerlink" title="按照时间线组织事件"></a>按照时间线组织事件</h2><p>按照用户使用业务的时间线进行事件组织,由这些事件组成合理的故事。</p><h2 id="加入界面以及命令"><a href="#加入界面以及命令" class="headerlink" title="加入界面以及命令"></a>加入界面以及命令</h2><p>事件由命令触发,来源可以是用户或者是外部系统。</p><h2 id="加入聚合关联命令和事件"><a href="#加入聚合关联命令和事件" class="headerlink" title="加入聚合关联命令和事件"></a>加入聚合关联命令和事件</h2><p>加入聚合后,可以继续完善缺失的事件。</p><h2 id="识别核心子域"><a href="#识别核心子域" class="headerlink" title="识别核心子域"></a>识别核心子域</h2><p>每一个核心子域都是一个完善的微服务,我们要做的是把这些子域分开,各子域之间不能相互依赖太多,修改时会相互牵扯。</p>]]></content>
<summary type="html">有一篇新的笔记✨</summary>
<category term="工具使用" scheme="http://example.com/categories/%E5%B7%A5%E5%85%B7%E4%BD%BF%E7%94%A8/"/>
<category term="工具" scheme="http://example.com/tags/%E5%B7%A5%E5%85%B7/"/>
<category term="笔记" scheme="http://example.com/tags/%E7%AC%94%E8%AE%B0/"/>
<category term="架构" scheme="http://example.com/tags/%E6%9E%B6%E6%9E%84/"/>
</entry>
<entry>
<title>React</title>
<link href="http://example.com/2024/06/24/React/"/>
<id>http://example.com/2024/06/24/React/</id>
<published>2024-06-24T04:14:35.000Z</published>
<updated>2024-07-10T03:33:05.804Z</updated>
<content type="html"><![CDATA[<p>本笔记是基于已有一定前端基础的情况下做的,如果看不懂建议看官方文档,还是看不懂建议上视频平台找博主视频手把手教。</p><blockquote><p>have fun😗</p></blockquote><h1 id="Next框架"><a href="#Next框架" class="headerlink" title="Next框架"></a>Next框架</h1><p>next对于react教程简单易懂,是我目前见过最友好的文档了,next补全了react的文档可以这么说。它不仅教你自己的脚手架怎么使用,还教你更新node、使用ts及tailwindcss,甚至还会让你跟着他一点点的改代码显示改出来的效果,让你答题恢复注意力,就和哄幼儿园的宝宝一样。</p><p>链接<a href="https://nextjs.org/learn/dashboard-app/getting-started">Learn Next.js: Getting Started | Next.js (nextjs.org)</a></p><blockquote><p>clsx库<a href="https://www.npmjs.com/package/clsx">clsx - npm (npmjs.com)</a> 可以结合JS/TS 条件更换样式</p></blockquote><blockquote><p>next 自带的组件库很好用嘞</p></blockquote><h2 id="页面路由"><a href="#页面路由" class="headerlink" title="页面路由"></a>页面路由</h2><p>对于<code>page.tsx</code>,它 是一个特殊的Next.js文件,用于导出 React 组件,并且需要它才能访问路由。</p><p>相当于你在app里面创建一个新的文件夹<code>new</code>下面放<code>page.tsx</code>后,访问页面路由<code>/new</code>就可以看到这个页面,他是文件夹形式的路由安排,而vite是将一份新的js文件如<code>route.js</code>写上页面的逻辑。</p><blockquote><p> next允许在不知道路由名称的时候创建路由,使用方括号<code>[]</code>设置。</p></blockquote><p>同样的对于css样式,next使用<code>layout.tsx</code>文件进行编写。这样就可以实现主页里的小页面进行更换了。</p><blockquote><p>对于/app/layout.tsx,其引用的文件是全局适用的,这被称为<code>根布局</code>。</p></blockquote><p>Link组件可以让用户在应用程序中页面链接。</p><blockquote><p>值得一提的是为了改善导航体验,Next.js 会自动按路由段对应用程序进行代码拆分。这与传统的 React SPA 不同,在传统的 React SPA 中,浏览器会在初始加载时加载所有应用程序代码。</p><p>按路由拆分代码意味着页面变得孤立。如果某个页面抛出错误,应用程序的其余部分仍将正常工作。</p></blockquote><p>在实际开发中我们经常会遇到需要用到路由name的时候,对于vue我们可以从我们写的路由js文件中找到<code>$route.path</code>等方式获取路由名称。而对于react,可以使用<code>usePathname()</code>的钩子来实现这个操作。</p><blockquote><p>添加 ‘use client’ 在文件顶部可以将此模块机器传递的依赖标记为客户端代码。 这些组件在用户设备上运行,并且可以使用浏览器API和React的状态和效果钩子,相对应的是’use server’。</p></blockquote><blockquote><p>tips:在第六章设置数据库那里,部署到vercel上会在seed组件报错,只需要删掉seed目录即可。详见<a href="https://github.com/vercel/next-learn/issues/768">Issue #768</a></p><p>同样的,当数据库配置好了之后再下下来/seed路径及其文件然后继续即可。</p></blockquote><h2 id="流媒体"><a href="#流媒体" class="headerlink" title="流媒体"></a>流媒体</h2><p>流式处理是一种数据传输技术,它允许您将路由分解为更小的“块”,并在它们准备就绪时逐步将它们从服务器流式传输到客户端。</p><blockquote><p>在next中loading.tsx是一个特殊的页面,会在对应页面加载时显示。</p></blockquote><p>React Suspense 可以更为精细的控制流媒体。</p><figure class="highlight tsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs tsx"><span class="hljs-keyword">import</span> { <span class="hljs-title class_">Suspense</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;<br></code></pre></td></tr></table></figure><p>这样做之后就可以用suspense标签包住想要精细化控制显示的路由了。</p><h2 id="部分预渲染"><a href="#部分预渲染" class="headerlink" title="部分预渲染"></a>部分预渲染</h2><p>Next.js 14 引入了部分预渲染的实验版本——一种新的渲染模型,允许在同一路线中结合静态和动态渲染的优势。</p><figure class="highlight tsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs tsx"><span class="hljs-comment">//next.config.mjs</span><br> <br><span class="hljs-keyword">const</span> nextConfig = {<br> <span class="hljs-attr">experimental</span>: {<br> <span class="hljs-attr">ppr</span>: <span class="hljs-string">'incremental'</span>,<br> },<br>};<br> <br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> nextConfig;<br><br><span class="hljs-comment">//组件</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> experimental_ppr = <span class="hljs-literal">true</span>;<br></code></pre></td></tr></table></figure><h2 id="搜索"><a href="#搜索" class="headerlink" title="搜索"></a>搜索</h2><p>这里采用URL搜索参数,以下是好处:</p><ul><li>可添加书签和可共享的 URL:由于搜索参数位于 URL 中,因此用户可以为应用程序的当前状态添加书签,包括其搜索查询和筛选器,以供将来参考或共享。</li><li>服务器端渲染和初始加载:可以直接在服务器上使用 URL 参数来渲染初始状态,从而更轻松地处理服务器渲染。</li><li>分析和跟踪:直接在 URL 中进行搜索查询和筛选,可以更轻松地跟踪用户行为,而无需额外的客户端逻辑。</li></ul><p>接下来我们要做的就是:</p><ul><li>获取用户的输入</li><li>使用搜索参数更新URL</li><li>保持URL和输入同步</li><li>更新表</li></ul><blockquote><p><code>URLSearchParams</code> 是一个 Web API,它提供用于操作 URL 查询参数的实用工具方法。可以使用它来获取参数字符串,而不是创建复杂的字符串文本,例如 <code>?page=1&query=a</code></p></blockquote><h3 id="消抖"><a href="#消抖" class="headerlink" title="消抖"></a>消抖</h3><p>在我们一开始handleSearch中,加入<code>console.log</code>测试,但是在控制台中输入<code>你好</code>我们可以看到:</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs markdown">n<br>ni<br>ni'h<br>ni'ha<br>ni'hao<br>你好<br></code></pre></td></tr></table></figure><blockquote><p>因为每次敲击键盘的时候都会更新URL,所以每次更新都会查询数据库,这明显是不合适的。</p></blockquote><p>我们采用停止键入延迟固定时间后才运行代码的方式进行消抖。</p><h2 id="处理错误"><a href="#处理错误" class="headerlink" title="处理错误"></a>处理错误</h2><p>对于正常遇到的错误,我们需要对其进行处理。</p><blockquote><p>在next中error.tsx是一个特殊的页面,会在对应页面错误时显示。</p></blockquote><p>如果是404页面,我们也许可以进行一些特殊处理。</p><figure class="highlight tsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs tsx"><span class="hljs-keyword">import</span> { notFound } <span class="hljs-keyword">from</span> <span class="hljs-string">'next/navigation'</span>;<br><span class="hljs-comment">//判断并调用</span><br><span class="hljs-title function_">notFound</span>();<br></code></pre></td></tr></table></figure><p>并在根目录下添加not-found.tsx,就在可以404返回状态下触发了。</p>]]></content>
<summary type="html">著名框架之一</summary>
<category term="技术栈" scheme="http://example.com/categories/%E6%8A%80%E6%9C%AF%E6%A0%88/"/>
<category term="前端" scheme="http://example.com/tags/%E5%89%8D%E7%AB%AF/"/>
<category term="笔记" scheme="http://example.com/tags/%E7%AC%94%E8%AE%B0/"/>
</entry>
<entry>
<title>MiniProgram</title>
<link href="http://example.com/2024/04/30/MiniProgram/"/>
<id>http://example.com/2024/04/30/MiniProgram/</id>
<published>2024-04-30T11:56:30.000Z</published>
<updated>2024-08-15T09:37:41.101Z</updated>
<content type="html"><![CDATA[<h1 id="踩坑的小笔记,不需要细看"><a href="#踩坑的小笔记,不需要细看" class="headerlink" title="踩坑的小笔记,不需要细看"></a>踩坑的小笔记,不需要细看</h1><p>发现运行打不开,说要配置好小程序的AppId,一个身份证号、一个手机号只能注册5个小程序。</p><blockquote><p>管理员身份验证还卡了我一下,说是要重新绑定一遍银行卡,成了。</p></blockquote><p>uniapp运行又打不开,要到微信开发者工具那里设置端口开放,全部关掉重开才行。</p><p>想用element-plus 好,他不给用;想用pinia,好,还是报错,刚刚问了一下,tailwind也是不能用的。哈哈。</p><p>去网上搜索了一下,原来uniapp本来就没什么好用的UI库,难绷。uniapp的风评更是依托。看到这我打算直接转回原生开发平台开发了。</p><p>哈哈。原本以为可以爽复制粘贴的项目,重构吧。</p><h2 id=""><a href="#" class="headerlink" title=""></a></h2><p>问题一:阿里的icon引不了,需要去icon库里下载,然后将download好的文件放入工作区,新建一个<code>iconfont.wxss</code>复制<code>iconfont.css</code>的内容。在<code>app.wxss</code>中<code>@import</code>引入<code>iconfont.wxss</code>。</p><p>还需要把最新的链接<code>@font-face</code>复制粘贴替换掉</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs html">//在wxml文件中 iconfont表示iconfont.wxss中默认引入源 icon-name表示图标类名,可以在下载的包的html中查看<br><span class="hljs-tag"><<span class="hljs-name">i</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"iconfont icon-name"</span>></span><span class="hljs-tag"></<span class="hljs-name">i</span>></span><br></code></pre></td></tr></table></figure><p>更新的时候要把文件替换,还要把在线链接换掉iconfont.wxss的在线链接换掉。</p><h2 id="-1"><a href="#-1" class="headerlink" title=""></a></h2><p>问题二:模拟器和真机调试的显示内容不一样。</p><h2 id="页面路由"><a href="#页面路由" class="headerlink" title="页面路由"></a>页面路由</h2><p>app.json下pages配置,页面内使用navigator标签进行跳转,一个文件夹下的wxml、wxss、js直接放一起打包了。</p><h2 id="高德地图"><a href="#高德地图" class="headerlink" title="高德地图"></a>高德地图</h2><p><a href="https://lbs.amap.com/api/wx/gettingstarted">入门指南-微信小程序插件 | 高德地图API (amap.com)</a></p><p>logo隐藏找了几篇都不行,决定overflowhidden完事。</p><h2 id="-2"><a href="#-2" class="headerlink" title=""></a></h2><p>引入JS文件需要让文件名大写。</p><h2 id="高德定位app-json配置"><a href="#高德定位app-json配置" class="headerlink" title="#高德定位app.json配置"></a>#高德定位app.json配置</h2><figure class="highlight prolog"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs prolog"><span class="hljs-string">"permission"</span>: {<br> <span class="hljs-string">"scope.userLocation"</span>: {<br> <span class="hljs-string">"desc"</span>: <span class="hljs-string">"你的位置信息将用于小程序位置接口的效果展示"</span><br> }<br> },<br> <span class="hljs-string">"requiredPrivateInfos"</span>: [<br> <span class="hljs-string">"chooseLocation"</span>,<br> <span class="hljs-string">"getLocation"</span><br> ]<br></code></pre></td></tr></table></figure><h2 id="-3"><a href="#-3" class="headerlink" title=""></a></h2><p>哈哈调用获得用户号码、身份证验证都需要钱。</p><h2 id="-4"><a href="#-4" class="headerlink" title=""></a></h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs JS"><span class="hljs-comment">//想要在success回调函数中改变data中的数据要</span><br><span class="hljs-attr">success</span>: <span class="hljs-function">(<span class="hljs-params">r</span>) =></span> {<br> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setData</span>({<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-number">1</span>)<br> })<br>}<br><span class="hljs-comment">//在主函数或者某个函数中打印要</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">data</span>)<br></code></pre></td></tr></table></figure><h2 id="-5"><a href="#-5" class="headerlink" title=""></a></h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//使用函数初始化data里的数据</span><br><span class="hljs-attr">onLoad</span>:<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){<br><span class="hljs-title function_">init</span>()<span class="hljs-comment">//初始化你data的操作</span><br><span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setData</span>({<br> <span class="hljs-attr">dataName</span>:<span class="hljs-variable language_">this</span>.<span class="hljs-property">data</span>.<span class="hljs-property">dataName</span><br>})<br>} <br></code></pre></td></tr></table></figure><h2 id="-6"><a href="#-6" class="headerlink" title=""></a></h2><p>如果下次写还是用uni吧,不是uni烂,是小程序烂</p><h2 id="-7"><a href="#-7" class="headerlink" title=""></a></h2><p>用div不用view的话盒子撑不开,比如你已经设置了w&h,但他还是会没有大小</p><h2 id="-8"><a href="#-8" class="headerlink" title=""></a></h2><p>小程序点击不能在函数后面加括号传参,要写个<code>data-xxx</code>然后在<code>e.currentTarget.dataset.xxx</code>里获取</p>]]></content>
<summary type="html">小程序就是依托,我说的。</summary>
<category term="技术栈" scheme="http://example.com/categories/%E6%8A%80%E6%9C%AF%E6%A0%88/"/>
<category term="前端" scheme="http://example.com/tags/%E5%89%8D%E7%AB%AF/"/>
<category term="笔记" scheme="http://example.com/tags/%E7%AC%94%E8%AE%B0/"/>
</entry>
<entry>
<title>Network</title>
<link href="http://example.com/2024/04/22/Network/"/>
<id>http://example.com/2024/04/22/Network/</id>
<published>2024-04-22T03:30:16.000Z</published>
<updated>2024-09-11T09:54:31.012Z</updated>
<content type="html"><![CDATA[<h2 id="网络协议"><a href="#网络协议" class="headerlink" title="网络协议"></a>网络协议</h2><h3 id="HTTP"><a href="#HTTP" class="headerlink" title="HTTP"></a>HTTP</h3><p><strong>(HyperText Transfer Protocol,超文本传输协议)</strong></p><h4 id="五层模型"><a href="#五层模型" class="headerlink" title="五层模型"></a>五层模型</h4><ul><li>应用层<ul><li>为应用软件提供了很多服务,构建于协议之上。</li></ul></li><li>传输层<ul><li>数据的传输都是在这层定义的,数据过大分包分片。</li></ul></li><li>网络层<ul><li>为数据在节点之间传输创建逻辑链路</li></ul></li><li>数据链路层<ul><li>通讯实体间建立数据链路连接。</li></ul></li><li>物理层<ul><li>主要作用是定义物理设备如何传输数据(光缆、网线)</li></ul></li></ul><h4 id="发展"><a href="#发展" class="headerlink" title="发展"></a>发展</h4><ul><li><p>HTTP 0.9</p><ul><li>只有一个GET,发送完毕就关闭tcp协议。</li></ul></li><li><p>HTTP 1.0</p><ul><li>增加了GET POST HEAD</li><li>Status Code</li><li>Header</li><li>多字符集支持</li><li>权限</li><li>缓存</li><li>内容编码</li><li>多部分发送</li></ul><blockquote><p>缺点:每个TCP连接都只能发送一个请求,发送数据完毕连接就关闭。如果还要请求其他资源就必须再新建一个连接。但是TCP新建连接的成本很高,因为客户端和服务器需要三次握手,而且刚开始发送的时候效率很慢。有些浏览器为了解决这个问题使用了一个非标准的Connection字段<code>Connection:Keep-alive</code>这个字段要求服务器不要关闭TCP连接,以便其他请求复用。</p></blockquote></li><li><p>HTTP 1.1</p><ul><li>增加了OPTIONS、PUT、PATCH、DELETE、TRACE、CONNECT</li><li>持久连接</li><li>增加host</li></ul><blockquote><p>缺点:虽然1.1版本支持TCP复用,但是同一个TCP连接中,所有数据通信是按照次序进行的,服务器只有处理完一个回应才会进行下一个回应。会造成<strong>队头堵塞</strong>,这就导致一些网页优化技巧:合并脚本和样式表、图片嵌入CSS代码、域名分片等。</p></blockquote></li><li><p>HTTP 2.0</p><ul><li>二进制传输</li><li>信道复用</li><li>分帧传输</li><li>Sever Push</li></ul></li></ul><h4 id="三次握手"><a href="#三次握手" class="headerlink" title="三次握手"></a>三次握手</h4><ul><li>第一次握手: 发送SYN报文, 传达信息: “你好, 我想建立连接”</li><li>第二次握手: 回传SYN+ACK报文, 传达信息: “好的, 可以建立链接”;</li><li>第三次握手: 回传ACK报文, 传到信息: “好的, 我知道了, 那我们连接”。然后建立连接</li></ul><blockquote><p>TCP为什么要进行三次握手:因为网络传输有延迟,客户端发送请求到服务器端要求建立连接,如果服务器端直接返回的话可能会产生丢 包的情况导致客户端接收不到数据,客户端会因为超时就关闭了,可能就去发送新的请求了,然而服务端并不知道丢包导致客户端没有接收数据,服务端端口就一直开着,造成了额外的开销。所以需要三次握手确认 这个过程。</p></blockquote><h4 id="报文"><a href="#报文" class="headerlink" title="报文"></a>报文</h4><ul><li>请求报文<ul><li>请求组成:请求行,消息报头,请求正文</li></ul></li><li>响应报文<ul><li>响应组成:状态行,消息报头,响应正文</li></ul></li></ul><h4 id="状态码"><a href="#状态码" class="headerlink" title="状态码"></a>状态码</h4><ul><li>1XX:指示信息–表示请求已接收,继续处理。</li><li>2XX:成功–表示请求已被成功接受、理解、接受。</li><li>3XX:重定向–要完成请求必须进一步操作。</li><li>4XX:客户端错误–请求有语法错误或无法实现。</li><li>5XX:服务端错误–服务端未能实现合法的请求。</li></ul><h4 id="Cache-Control"><a href="#Cache-Control" class="headerlink" title="Cache-Control"></a>Cache-Control</h4><p>Cache-Control 是一个 <strong>HTTP 协议中关于缓存的响应头</strong>,它由一些能够允许你定义一个响应资源应该何时、如何被缓存以及缓存多长时间的指令组成。 当浏览器保存了资源的副本从而达到 快速访问的目的 的时候也就是 HTTP 发生了缓存。</p><ul><li>可缓存性:<ul><li>public 任何都可以</li><li>private 只有它发起浏览器可以缓存</li><li>no-cache 去服务端验证才能使用</li><li>no-store 彻底不能</li><li>no-transform 代理服务器、客户端实体不能改动返回内容</li></ul></li><li>到期时间<ul><li>max-age 最大时间</li><li>s-maxage 只有在代理服务器才会生效</li><li>max-stale 只能在发起端设置 就算max-age时间过期 max-stale时间没过期也会走缓存</li></ul></li></ul><h4 id="长连接"><a href="#长连接" class="headerlink" title="长连接"></a>长连接</h4><p>Connection:keep-alive/close 打开关闭</p><p>打开的话就是TCP连接上把HTTP请求的内容发送并接受完返回,不需要多次握手。</p><p>这里可以设置关闭时间,也有些浏览器会有TCP并发限制,比如Chrome浏览器就是6次并发请求限制。</p><h4 id="数据协商"><a href="#数据协商" class="headerlink" title="数据协商"></a>数据协商</h4><ul><li><p>请求</p><ul><li><p>Accept 什么类型</p></li><li><p>Accept-Encoding 压缩方式</p></li><li><p>Accept-Language 语言 </p></li><li><p>user-Agent 浏览器信息</p></li></ul></li><li><p>返回</p><ul><li><p>Content-type 类型</p></li><li><p>Content-Encoding 压缩类型</p></li><li><p>Content-Language 语言</p></li></ul></li></ul><h4 id="CSP-内容安全策略"><a href="#CSP-内容安全策略" class="headerlink" title="CSP 内容安全策略"></a>CSP 内容安全策略</h4><ul><li>限制方式:Content-Security-Policy:””</li></ul><p>如果没有按照限制的方式加载会发回一个错误信息</p><h3 id="HTTPS"><a href="#HTTPS" class="headerlink" title="HTTPS"></a>HTTPS</h3><p>HTTPS是通过握手进行加密,通过公钥进行加密,通过私钥进行解密。</p><ul><li>流程<ul><li>客户端请求服务器获取<code>证书公钥</code></li><li>客户端解析证书</li><li>生成随机值</li><li>用<code>公钥加密</code>随机值生成密钥</li><li>客户端将<code>秘钥</code>发送给服务器</li><li>服务器用<code>私钥</code>解密得到随机值</li><li>将信息和随机值混合在一起进行对称加密</li><li>将加密的内容发送给客户端</li><li>客户端用<code>秘钥</code>解密信息</li></ul></li></ul><h3 id="跨域"><a href="#跨域" class="headerlink" title="跨域"></a>跨域</h3><h4 id="跨域原因"><a href="#跨域原因" class="headerlink" title="跨域原因"></a>跨域原因</h4><p>浏览器的同源策略限制了跨域请求资源。</p><h4 id="JSONP跨域"><a href="#JSONP跨域" class="headerlink" title="JSONP跨域"></a>JSONP跨域</h4><p>JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问。具体来说,当一个网页想要从另一个域名获取数据时,它会向那个域名发送一个请求,然后在返回的响应中插入一段script标签,这段标签的src属性就是数据所在的URL。这样,浏览器就会去执行这段script标签中的JavaScript代码,从而获取到数据。但是这种方法存在一定的安全风险,因为它绕过了浏览器的同源策略。</p><h4 id="跨域的限制"><a href="#跨域的限制" class="headerlink" title="跨域的限制"></a>跨域的限制</h4><ul><li>默认跨域允许的方法只有GET、POST、HEAD,其他的方法都不允许。</li><li>默认允许Content-type以下三个,其他的预请求验证,通过就能发送。<ul><li>text/plain</li><li>multipart/form-data</li><li>application/x-www-form-urlencoded</li></ul></li><li>请求头限制,自定义的请求头是不允许的,预请求验证才能通过。</li></ul><h2 id="Cookie-amp-Session-amp-Token-的区别"><a href="#Cookie-amp-Session-amp-Token-的区别" class="headerlink" title="Cookie & Session & Token 的区别"></a>Cookie & Session & Token 的区别</h2><h3 id="Cookies"><a href="#Cookies" class="headerlink" title="Cookies"></a>Cookies</h3><p>客户端的浏览器发出HTTP请求,服务器会进行Cookie设置,也就是set-Cookie,Cookie发送给浏览器之后,浏览器会保存起来,之后发送的每一个请求都会附上这个Cookie。</p><p>但是Cookie本身是有有被篡改风险的,同时用户可能禁用、容量限制4KB。</p><h3 id="Session"><a href="#Session" class="headerlink" title="Session"></a>Session</h3><p>相当于加密版的Cookie,首先也是浏览器发出HTTP请求,服务器这边会设置一个SessionID,并把此ID和会话结束时间一起记录到Cookie返回到客户端,然后不带有用户的密码,只带有SessionID和会话结束时间,在结束时间到的时候就删除cookie,然后由于cookie性质,每次访问都会附上cookie,所以就可以实现长时间登录了。</p><p>但是如果多很多用户,那么SessionID对于服务器将是一个巨大的负担;如果拥有多台服务器的话,那么SessionID又需要去共享给每一台服务器。太笨拙了。</p><h3 id="Token"><a href="#Token" class="headerlink" title="Token"></a>Token</h3><p>多服务器的情况下,如果想要存储SessionID的话,可以放到数据库中,但是如果数据库和后端连接的某个地方又炸了呢。种种情况下催生出了JWT(JSON Web Token)</p><p>也是像上面那样的,首先是浏览器发出HTTP请求,给到一个JSON格式的账号密码给服务端,服务端将其转化为JWT签名密文发给客户端,根据Cookie的性质,每次都会把JWT密文发回给服务端,这样就可以认证登录了。</p><blockquote><p>JWT是由三个部分构成的 <code>header</code>.<code>payload</code>.<code>signature</code></p><p><code>header</code>部分声明需要用什么算法来生成签名。<br><code>payload</code>部分是一些特殊的数据,比如有效期之类的。</p><p><code>header</code> <code>payload</code>的JSON格式Base64编码之后 服务器保存的一段密码对这俩进行算法运算,算出来的东西就是<code>signature</code></p></blockquote><h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><p>Cookie是一个载体,Session是保存在服务器那边的下信息,Token是诞生于服务器但是保存在浏览器这边。</p><h2 id="Session-Storage-amp-Local-Storage-amp-Cookie-的区别"><a href="#Session-Storage-amp-Local-Storage-amp-Cookie-的区别" class="headerlink" title="Session Storage & Local Storage & Cookie 的区别"></a>Session Storage & Local Storage & Cookie 的区别</h2><h3 id="Session-Storage"><a href="#Session-Storage" class="headerlink" title="Session Storage"></a>Session Storage</h3><p>Session Storage 是用于本地存储一个会话中的数据,当会话结束时数据就会被销毁,也就是浏览器关闭的时候就会被销毁。<strong>Session Storage 和 Session 不是一个东西</strong> 。</p><p>是 Web Storage 用于本地存储的一个方式。</p><h3 id="Local-Storage"><a href="#Local-Storage" class="headerlink" title="Local Storage"></a>Local Storage</h3><p>Local Storage 是持久化的存储数据,不删除(通过各种方式)是不会消失的。</p><p>是 Web Storage 用于本地存储的一个方式。</p><h3 id="Cookie"><a href="#Cookie" class="headerlink" title="Cookie"></a>Cookie</h3><p>Cookie 是存储在浏览器端的一小段文本数据,每次向服务端发送请求的时候Cookie都会被发送过去。故Cookie不能作为前端的数据缓存。将token存储到cookie中一般是由后端实现。</p><p>是HTTP规范的一部分。</p>]]></content>
<summary type="html">网络层及其周边知识的学习</summary>
<category term="技术栈" scheme="http://example.com/categories/%E6%8A%80%E6%9C%AF%E6%A0%88/"/>
<category term="前端" scheme="http://example.com/tags/%E5%89%8D%E7%AB%AF/"/>
<category term="笔记" scheme="http://example.com/tags/%E7%AC%94%E8%AE%B0/"/>
</entry>
<entry>
<title>Amap</title>
<link href="http://example.com/2024/04/08/Amap/"/>
<id>http://example.com/2024/04/08/Amap/</id>
<published>2024-04-08T09:39:27.000Z</published>
<updated>2024-04-24T11:03:04.582Z</updated>
<content type="html"><![CDATA[<h2 id="高德地图api使用"><a href="#高德地图api使用" class="headerlink" title="高德地图api使用"></a>高德地图api使用</h2><p><a href="https://lbs.amap.com/api/javascript-api-v2/summary">概述-地图 JS API 2.0|高德地图API (amap.com)</a></p><h3 id="Vue-使用前准备"><a href="#Vue-使用前准备" class="headerlink" title="Vue 使用前准备"></a>Vue 使用前准备</h3><ul><li><p>首先登录高德,注册成为开发者,创建key,服务平台选择Web端(JS API)。</p></li><li><p>进入工作区:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell"> npm i @amap/amap-jsapi-loader --save<br></code></pre></td></tr></table></figure></li><li><p>在需要使用的组件下:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">import</span> <span class="hljs-title class_">AMapLoader</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'@amap/amap-jsapi-loader'</span>;<br></code></pre></td></tr></table></figure></li><li><p>示例代码</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><code class="hljs vue"><script setup><br>import { onMounted, onUnmounted } from "vue";<br>import AMapLoader from "@amap/amap-jsapi-loader";<br><br>let map = null;<br><br>onMounted(() => {<br> AMapLoader.load({<br> key: "", // 申请好的Web端开发者Key,首次调用 load 时必填<br> version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15<br> plugins: ["AMap.Scale"], //需要使用的的插件列表,如比例尺'AMap.Scale',支持添加多个如:['...','...']<br> })<br> .then((AMap) => {<br> map = new AMap.Map("container", {<br> // 设置地图容器id<br> viewMode: "3D", // 是否为3D地图模式<br> zoom: 11, // 初始化地图级别<br> center: [116.397428, 39.90923], // 初始化地图中心点位置<br> });<br> })<br> .catch((e) => {<br> console.log(e);<br> });<br>});<br><br>onUnmounted(() => {<br> map?.destroy();<br>});<br></script><br><br><template><br> <div id="container"></div><br></template><br><br><style scoped><br>#container {<br> width: 100%;<br> height: 800px;<br>}<br></style><br></code></pre></td></tr></table></figure></li></ul><h3 id="Vue-水印去除"><a href="#Vue-水印去除" class="headerlink" title="Vue 水印去除"></a>Vue 水印去除</h3><p>在index.html中加上:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">style</span>></span><span class="language-css"></span><br><span class="language-css"> <span class="hljs-selector-class">.amap-logo</span> {</span><br><span class="language-css"> <span class="hljs-attribute">display</span>: none;</span><br><span class="language-css"> <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;</span><br><span class="language-css"> }</span><br><span class="language-css"> </span><br><span class="language-css"> <span class="hljs-selector-class">.amap-copyright</span> {</span><br><span class="language-css"> <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0</span>;</span><br><span class="language-css"> }</span><br><span class="language-css"> </span><span class="hljs-tag"></<span class="hljs-name">style</span>></span><br></code></pre></td></tr></table></figure>]]></content>
<summary type="html">高德API小小标记一下</summary>
<category term="工具使用" scheme="http://example.com/categories/%E5%B7%A5%E5%85%B7%E4%BD%BF%E7%94%A8/"/>
<category term="工具" scheme="http://example.com/tags/%E5%B7%A5%E5%85%B7/"/>
<category term="前端" scheme="http://example.com/tags/%E5%89%8D%E7%AB%AF/"/>
</entry>
<entry>
<title>Pinia</title>
<link href="http://example.com/2024/03/25/Pinia/"/>
<id>http://example.com/2024/03/25/Pinia/</id>
<published>2024-03-25T08:31:57.000Z</published>
<updated>2024-04-06T13:22:26.336Z</updated>
<content type="html"><![CDATA[<h1 id="Pinia简介"><a href="#Pinia简介" class="headerlink" title="Pinia简介"></a>Pinia简介</h1><p>Pinia 是 Vue 的专属状态管理库,可以同时支持vue2和vue3,它允许你跨组件或页面共享状态。如果你熟悉组合式 API 的话,你可能会认为可以通过一行简单的 <code>export const state = reactive({})</code> 来共享一个全局状态。对于单页应用来说确实可以,但如果应用在服务器端渲染,这可能会使你的应用暴露出一些<a href="https://cn.vuejs.org/guide/scaling-up/ssr#cross-request-state-pollution">安全漏洞</a>。 而如果使用 Pinia,即使在小型单页应用中,你也可以获得如下功能:</p><ul><li>Devtools 支持<ul><li>追踪 actions、mutations 的时间线</li><li>在组件中展示它们所用到的 Store</li><li>让调试更容易的 Time travel</li></ul></li><li>热更新<ul><li>不必重载页面即可修改 Store</li><li>开发时可保持当前的 State</li></ul></li><li>插件:可通过插件扩展 Pinia 功能</li><li>为 JS 开发者提供适当的 TypeScript 支持以及<strong>自动补全</strong>功能。</li><li>支持服务端渲染</li></ul><p>Pinia其实就是Vuex5,所以他们是一样的东西。</p><p>它拥有比MITT更多的功能。而且也没有遇到兄弟组件传值出现的问题。好用。</p><h1 id="Pinia安装"><a href="#Pinia安装" class="headerlink" title="Pinia安装"></a>Pinia安装</h1><p><a href="https://pinia.vuejs.org/zh/getting-started.html">Pinia官网</a></p><p>Nodejs包管理器下载:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">npm install pinia<br></code></pre></td></tr></table></figure><p>vite配置</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//main.js</span><br><span class="hljs-keyword">import</span> { createApp } <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span><br><span class="hljs-keyword">import</span> { createPinia } <span class="hljs-keyword">from</span> <span class="hljs-string">'pinia'</span><br><span class="hljs-keyword">const</span> pinia = <span class="hljs-title function_">createPinia</span>()<br><span class="hljs-title function_">createApp</span>(<span class="hljs-title class_">App</span>).<span class="hljs-title function_">use</span>(pinia).<span class="hljs-title function_">mount</span>(<span class="hljs-string">'#app'</span>)<br></code></pre></td></tr></table></figure><h1 id="Store"><a href="#Store" class="headerlink" title="Store"></a>Store</h1><h3 id="Store简介"><a href="#Store简介" class="headerlink" title="Store简介"></a>Store简介</h3><p>Store (如 Pinia) 是一个保存状态和业务逻辑的实体,它并不与你的组件树绑定。换句话说,<strong>它承载着全局状态</strong>。它有点像一个永远存在的组件,每个组件都可以读取和写入它。它有<strong>三个概念</strong>,<a href="https://pinia.vuejs.org/zh/core-concepts/state.html">state</a>、<a href="https://pinia.vuejs.org/zh/core-concepts/getters.html">getter</a> 和 <a href="https://pinia.vuejs.org/zh/core-concepts/actions.html">action</a>,我们可以假设这些概念相当于组件中的 <code>data</code>、 <code>computed</code> 和 <code>methods</code>。</p><h3 id="Store使用"><a href="#Store使用" class="headerlink" title="Store使用"></a>Store使用</h3><p>先创建一个js/ts文件。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//我是直接创到了public目录下 /public/store/user.js</span><br><span class="hljs-keyword">import</span> { defineStore } <span class="hljs-keyword">from</span> <span class="hljs-string">'pinia'</span><br><span class="hljs-keyword">import</span> { ref,computed } <span class="hljs-keyword">from</span> <span class="hljs-string">"vue"</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> useCounterStore = <span class="hljs-title function_">defineStore</span>(<span class="hljs-string">'counter'</span>, <span class="hljs-function">() =></span> {<br> <span class="hljs-keyword">const</span> count = <span class="hljs-title function_">ref</span>(<span class="hljs-number">0</span>)<br> <span class="hljs-keyword">const</span> doubleCount = <span class="hljs-title function_">computed</span>(<span class="hljs-function">() =></span> count.<span class="hljs-property">value</span> * <span class="hljs-number">2</span>)<br> <span class="hljs-keyword">function</span> <span class="hljs-title function_">increment</span>(<span class="hljs-params"></span>) {<br> count.<span class="hljs-property">value</span>++<br> }<br><br> <span class="hljs-keyword">return</span> { count, doubleCount, increment }<br>})<br></code></pre></td></tr></table></figure><p>然后直接使用:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">import</span> { useCounterStore } <span class="hljs-keyword">from</span> <span class="hljs-string">'/public/stores/user.js'</span><br><span class="hljs-keyword">const</span> store = <span class="hljs-title function_">useCounterStore</span>()<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(store.<span class="hljs-property">count</span>)<br></code></pre></td></tr></table></figure><p>就行了,感觉比MITT方便不少,store似乎就是一个reactive对象。可以解构。</p>]]></content>
<summary type="html">Pinia 是 Vue 的专属状态管理库,允许你跨组件或页面共享状态。</summary>
<category term="技术栈" scheme="http://example.com/categories/%E6%8A%80%E6%9C%AF%E6%A0%88/"/>
<category term="前端" scheme="http://example.com/tags/%E5%89%8D%E7%AB%AF/"/>
<category term="笔记" scheme="http://example.com/tags/%E7%AC%94%E8%AE%B0/"/>
</entry>
<entry>
<title>AutoHotKey</title>
<link href="http://example.com/2024/03/01/AutoHotKey/"/>
<id>http://example.com/2024/03/01/AutoHotKey/</id>
<published>2024-03-01T05:33:37.000Z</published>
<updated>2024-03-09T07:00:54.242Z</updated>
<content type="html"><![CDATA[<p>工作的时候手碰着键盘就不想去动鼠标了,但是有一些常用的文件夹或者软件需要点点点点开,就算把他放在桌面或者开始界面都还是需要点点点,那么对于我们这种快捷键爱好者应该怎么设置一个全局快捷键呢。</p><p>本来呢这篇文章是关于 文件夹/软件全局快捷键设置的 但是我使用的方法吧他时灵时不灵</p><blockquote><p>就是创快捷方式点属性改快捷键</p></blockquote><p>虽然偶尔能打开,但是更多的是按完快捷键卡顿很久才打开或者干脆开不开了,很蠢。</p><p>干脆去找桌面脚本语言了。</p><h1 id="AutoHotKey"><a href="#AutoHotKey" class="headerlink" title="AutoHotKey"></a>AutoHotKey</h1><p>找到了这个,这玩意好用啊,无论是文件还是网站都可以快速打开,真的很爽。</p><p>现在只是探索了一个简单的使用方法,还有很多可以尝试来着。</p><p><a href="https://www.autohotkey.com/">AutoHotkey</a> </p><h3 id="基本使用"><a href="#基本使用" class="headerlink" title="基本使用"></a>基本使用</h3><ul><li><p>首先就是进行一个2.0版本的下载。</p></li><li><p>下载完成之后是一个autohotkey dash,新建一个empty文件,直接用右键啥方式打开都行(我是vscode),进去编写。</p></li><li><p>编写好了右键使用其他方式打开,找到autohotkey目录下的<code>AutoHotkeyU64.exe</code>打开 一路确定</p></li><li><p>然后双击你写的脚本文件,就开始运行了。</p></li></ul><h3 id="基础语法"><a href="#基础语法" class="headerlink" title="基础语法"></a>基础语法</h3><ul><li><p><code>;</code>是注释</p></li><li><p>热键:</p><ul><li><code>#</code>:win键</li><li><code>!</code>:alt键</li><li><code>^</code>:ctrl键</li><li><code>+</code>:shift键</li></ul></li><li><p>连接符是<code>::</code> 用于连接热键和运行</p></li><li><p>运行是 <code>Run</code> 运行后面跟文件路径、网址、程序</p></li><li><p>示例:</p><figure class="highlight ahk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs ahk"><span class="hljs-comment">;ctrl+shift+z 打开c盘</span><br><span class="hljs-title">^+z::</span>Run C:\<br></code></pre></td></tr></table></figure></li></ul><h3 id="开机自启动"><a href="#开机自启动" class="headerlink" title="开机自启动"></a>开机自启动</h3><p>如果需要不双击运行而是一开机就运行,那么执行以下操作</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs bash">把写好的脚本放到<br>{C:\Users\用户名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup}<br>或者也可能是<br>{C:\用户\用户名\AppData\Roaming\Microsoft\Windows\开始菜单\程序\启动}<br></code></pre></td></tr></table></figure><p>这样之后每次开电脑就会打开,虽然不是马上开,等个几秒就可以了</p>]]></content>
<summary type="html">AutoHotKey是一个脚本语言,用来编写一个简单的脚本还是很方便的。</summary>
<category term="工具使用" scheme="http://example.com/categories/%E5%B7%A5%E5%85%B7%E4%BD%BF%E7%94%A8/"/>
<category term="工具" scheme="http://example.com/tags/%E5%B7%A5%E5%85%B7/"/>
<category term="快捷使用" scheme="http://example.com/tags/%E5%BF%AB%E6%8D%B7%E4%BD%BF%E7%94%A8/"/>
</entry>
<entry>
<title>Nginx</title>
<link href="http://example.com/2024/01/30/Nginx/"/>
<id>http://example.com/2024/01/30/Nginx/</id>
<published>2024-01-30T12:53:18.000Z</published>
<updated>2024-03-16T11:46:48.063Z</updated>
<content type="html"><![CDATA[<p>下载路径:<a href="https://nginx.org/en/download.html">nginx下载</a></p><p>Nginx是目前最流行的web服务器,同类型的还有Apache、Cloudflare、OpenResty。最开始是由⼀个叫做igor的俄罗斯的程序员开发的,2019年3⽉11⽇被美国的F5公司以6.7亿美元的价格收购,现在Nginx是F5公司旗下的⼀款产品了。</p><h1 id="Nginx进程模型"><a href="#Nginx进程模型" class="headerlink" title="Nginx进程模型"></a>Nginx进程模型</h1><ul><li>Master进程是Nginx的主进程,负责读取和验证配置文件。</li><li>worker进程就是nginx的工作进程,负责处理实际的请求。</li><li>master进程只可以有一个,但是worker进程可以有很多个。</li></ul><h1 id="Nginx部署静态资源"><a href="#Nginx部署静态资源" class="headerlink" title="Nginx部署静态资源"></a>Nginx部署静态资源</h1><p>nginx静态资源部署运行时需要开任务管理器检查是否存在。</p><p>子文件夹:</p><ul><li>html:用于放你需要部署的、打包好的静态资源。tips:直接放有html的那一堆不要再多包一个文件夹了。</li><li>logs:用于放每次运行的情况。</li><li>conf:是配置,可以在nginx.conf中修改端口号,默认80,如果占用就会报错,可修改。<ul><li>端口号:需要修改时打开nginx.conf文件,找到server->listen 修改后面端口号即可</li></ul></li></ul><h1 id="Nginx配置文件"><a href="#Nginx配置文件" class="headerlink" title="Nginx配置文件"></a>Nginx配置文件</h1><h3 id="配置文件的结构"><a href="#配置文件的结构" class="headerlink" title="配置文件的结构"></a>配置文件的结构</h3><p>Nginx的配置⽂件是由⼀系列的指令组成的,每个指令都是由⼀个指令名和⼀个或者多个参数组成的。</p><p>指令和参数之间使⽤空格来分隔,指令以分号 ; 结尾,参数可以使⽤单引号或者双引号来包裹。</p><p>配置⽂件分为以下⼏个部分:</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs nginx"><span class="hljs-comment"># 全局块</span><br><br><span class="hljs-attribute">worker_processes</span> <span class="hljs-number">1</span>;<br><br><span class="hljs-section">events</span> {<br><span class="hljs-comment"># events块</span><br>}<br><span class="hljs-section">http</span> {<br> <span class="hljs-comment"># http块</span><br> <span class="hljs-section">server</span> {<br><span class="hljs-comment"># server块</span><br> <span class="hljs-section">location</span> / {<br> <span class="hljs-comment"># location块</span><br> }<br> }<br>}<br></code></pre></td></tr></table></figure><h5 id="全局块"><a href="#全局块" class="headerlink" title="全局块"></a>全局块</h5><ul><li>worker_processes是用于控制worker进程数量的,也可以设置auto,worker进程数量保持同服务器CPU内核数量相同比较合适</li><li>其他一些能配置的东西包括运行Nginx服务器的用户组、进程PID存放路径、日志存放路径和类型以及配置文件引入等。</li></ul><h5 id="events块"><a href="#events块" class="headerlink" title="events块"></a>events块</h5><blockquote><p>用于配置客户端和服务器网络连接的一些配置。比如指定每个worker进程可以接收多少个网络连接、网络IO模型等。</p></blockquote><ul><li>use:指定使用哪种网络IO模型,只能在events块中进行配置。</li><li>worker_connections:每个worker process允许链接的最大连接数。</li></ul><h5 id="http块"><a href="#http块" class="headerlink" title="http块"></a>http块</h5><blockquote><p>虚拟主机、反向代理、负载均衡等都在这里配置,http块可以包含很多server块又叫虚拟主机。</p></blockquote><ul><li>include:nginx可以使用include指令引入其他配置文件。</li><li>default_type:默认类型,如果请求的URL没有包含文件类型,会使用默认类型。</li><li>sendflie:开启高效文件传输模式。</li><li>keepalive_timeout:连接超时时间。</li><li>access_log:日志的存放路径和类型。</li><li>log_format:自定义日志格式。</li><li>sendfile_max_chunk:设置sendfile最⼤传输⽚段⼤⼩,默认为0,表示不限制。</li><li>keepalive_requests:每个连接的请求次数。</li><li>keepalive_timeout: keepalive超时时间。</li><li>gzip:开启gzip压缩。</li><li>gzip_min_length: 开启gzip压缩的最⼩⽂件⼤⼩。</li><li>gzip_comp_level:gzip压缩级别,1-9,级别越⾼压缩率越⾼,但是消耗CPU资源也越多。</li><li>gzip_types:gzip压缩⽂件类型。</li><li>upstream: upstream指令⽤于定义⼀组服务器,⼀般⽤来配置反向代理和负载均衡。</li><li>ip_hash指令⽤于设置负载均衡的⽅式,ip_hash表示使⽤客户端的IP进⾏hash,这样可以保证同⼀个客户端的请求每次都会分配到同⼀个服务器,解决了session共享的问题。</li><li>weight ⽤于设置权重,权重越⾼被分配到的⼏率越⼤</li></ul><h5 id="server块"><a href="#server块" class="headerlink" title="server块"></a>server块</h5><ul><li><p>listen:监听IP和端⼝。</p><ul><li>listen指令⾮常灵活,可以指定多个IP和端⼝,也可以使⽤通配符</li></ul> <figure class="highlight clean"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs clean">下⾯是⼏个实际的例⼦:<br># listen <span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>:<span class="hljs-number">80</span>; # 监听来⾃<span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>的<span class="hljs-number">80</span>端⼝的请求<br># listen <span class="hljs-number">80</span>; # 监听来⾃所有IP的<span class="hljs-number">80</span>端⼝的请求<br># listen *:<span class="hljs-number">80</span>; # 监听来⾃所有IP的<span class="hljs-number">80</span>端⼝的请求,同上<br># listen <span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>; # 监听来⾃来⾃<span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>的<span class="hljs-number">80</span>端⼝,默认端⼝为<span class="hljs-number">80</span><br></code></pre></td></tr></table></figure></li><li><p>server_name:⽤来指定虚拟主机的域名,可以使⽤精确匹配、通配符匹配和正则匹配等⽅式</p></li><li><p>location:location块⽤来配置请求的路由,⼀个server块可以包含多个location块,每个location块就是⼀个请求路由。</p><ul><li>root:root指令⽤于指定请求的根⽬录,可以是绝对路径,也可以是相对路径</li><li>index:index指令⽤于指定默认⽂件,如果请求的是⽬录,则会在⽬录下查找默认⽂件</li></ul></li><li><p>error_page:⽤于指定错误⻚⾯,可以指定多个,按照优先级从⾼到低依次查找</p></li></ul><h1 id="Nginx的常用模块"><a href="#Nginx的常用模块" class="headerlink" title="Nginx的常用模块"></a>Nginx的常用模块</h1><ul><li><p>http_access_module :接受或者拒绝特定的客户端请求</p></li><li><p>http_auth_basic_module :HTTP基本认证,使用用户名和密码来限制对资源的访问</p></li><li><p>http_autoindex_module :⾃动索引,⽤于显示⽬录列表</p></li><li><p>http_browser_module :从 User-Agent 请求头中获取和识别客户端浏览器</p></li><li><p>http_charset_module :添加特定的字符集到 Content-Type 响应头中</p></li><li><p>http_empty_gif_module :返回⼀个1像素的透明GIF图⽚</p></li><li><p>http_fastcgi_module :FastCGI⽀持</p></li><li><p>http_geo_module :从IP地址中获取地理位置信息</p></li><li><p>http_gzip_module :Gzip压缩⽀持</p></li><li><p>http_limit_conn_module :限制并发连接数</p></li><li><p>http_limit_req_module :限制请求速率</p></li><li><p>http_map_module :从变量中获取值</p></li><li><p>http_memcached_module :Memcached⽀持</p></li><li><p>http_proxy_module :反向代理⽀持</p></li><li><p>http_referer_module :防盗链</p></li><li><p>http_rewrite_module :URL重写</p></li><li><p>http_scgi_module :转发请求到SCGI服务器</p></li><li><p>http_ssi_module :处理和⽀持SSI(Server Side Includes)</p></li><li><p>http_split_clients_module :根据客户端IP地址或者其他变量将客户端分配到组中,⼀般⽤于A/B测试</p></li><li><p>http_upstream_hash_module :启⽤⼀致性哈希负载均衡</p></li><li><p>http_upstream_ip_hash_module :启⽤IP哈希负载均衡</p></li><li><p>http_upstream_keepalive_module :启⽤⻓连接负载均衡</p></li><li><p>http_upstream_least_conn_module :启⽤最少连接负载均衡</p></li><li><p>http_upstream_zone_module :启⽤共享内存负载均衡</p></li><li><p>http_userid_module :为客户端设置⼀个唯⼀的ID(UID、cookie)</p></li><li><p>http_uwsgi_module :转发请求到uWSGI服务器,⼀般⽤于Python应⽤</p></li></ul><h1 id="Nginx反向代理"><a href="#Nginx反向代理" class="headerlink" title="Nginx反向代理"></a>Nginx反向代理</h1><blockquote><p>正向代理:正向代理就是代理客户端,比如想访问某些国外网站的时候访问不了,这个时候就需要VPN代理服务器进行正向代理,帮你代理客户端</p></blockquote><blockquote><p>反向代理:反向代理就是代理服务端,比如访问一个网站的时候,比如访问咕噜咕噜(Google),他有很多很多服务器,但是对外暴露的只有一个域名,那我们访问的请求会被转发到后面的服务器上,真实的端口IP服务器信息被隐藏。</p></blockquote><h3 id="第一步:在upstream里面放服务器配置:"><a href="#第一步:在upstream里面放服务器配置:" class="headerlink" title="第一步:在upstream里面放服务器配置:"></a>第一步:在upstream里面放服务器配置:</h3><p>在upstream后面是一个名字类似Vue路由配置中的name,可以随便取。</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs nginx"><span class="hljs-section">upstream</span> name {<br><span class="hljs-attribute">server</span> <span class="hljs-number">127.0.0.1:8000</span>;<br> <span class="hljs-attribute">server</span> <span class="hljs-number">127.0.0.1:8001</span>;<br> <span class="hljs-attribute">server</span> <span class="hljs-number">127.0.0.1:8002</span>;<br> ...(启动的服务)<br>}<br></code></pre></td></tr></table></figure><p>有时候后台服务器的性能可能不同,以下为两种策略:</p><ul><li>ip_hash指令⽤于设置负载均衡的⽅式,ip_hash表示使⽤客户端的IP进⾏hash,这样可以保证同⼀个客户端的请求每次都会分配到同⼀个服务器,解决了session共享的问题。</li><li>weight:⽤于设置权重,权重越⾼被分配到的⼏率越⼤,用于分流。</li></ul><h3 id="第二步:在localtion中配置:"><a href="#第二步:在localtion中配置:" class="headerlink" title="第二步:在localtion中配置:"></a>第二步:在localtion中配置:</h3><p>localtion后面的/…是自己取的名字,意思是将所有访问<a href="http://app的请求发送到前面取的name里,/">http://app的请求发送到前面取的name里,</a></p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs nginx"><span class="hljs-attribute">localtion</span> /route {<br> <span class="hljs-attribute">proxy_pass</span> http://name;<br>}<br></code></pre></td></tr></table></figure><p>这样请求都被代理到我们所有服务器中,默认是以轮询的方式来代理。</p><h1 id="HTTPS配置"><a href="#HTTPS配置" class="headerlink" title="HTTPS配置"></a>HTTPS配置</h1><h3 id="证书"><a href="#证书" class="headerlink" title="证书"></a>证书</h3><p>HTTP默认端口是80,HTTPS默认端口是443。</p><p>HTTPS协议需要使用到SSL证书,主流云平台上都可以申请到SSL证书,也可以通过openssl生成一个自签名的证书。</p><figure class="highlight vbnet"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs vbnet">生成私钥文件:<br>openssl genrsa -out <span class="hljs-keyword">private</span>.<span class="hljs-keyword">key</span> <span class="hljs-number">2048</span><br>根据私钥生成证书签名请求文件:<br>openssl req -<span class="hljs-built_in">new</span> -<span class="hljs-keyword">key</span> <span class="hljs-keyword">private</span>.<span class="hljs-keyword">key</span> -out cert.csr<br>使用私钥对证书申请进行签名从而生成证书文件:<br>openssl x509 -req -<span class="hljs-keyword">in</span> cert.csr -out cacert.pem -signkey <span class="hljs-keyword">private</span>.<span class="hljs-keyword">key</span><br></code></pre></td></tr></table></figure><h3 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h3><p>在server中修改listen监听端口,改为 <code>443 ssl</code></p><ul><li>ssl_certificate:用于放证书文件路径(填入完整证书链可以不报红)</li><li>ssl_certificate_key:用于放证书私钥文件路径(填入完整证书链可以不报红)</li><li>ssl_session_timeout:缓存有效期</li><li>ssl_protocols:安全链接可选的加密协议</li><li>ssl_ciphers:配置加密套件/加密算法</li><li>ssl_prefer_server_ciphers:使用服务器端的首选算法</li></ul><h3 id="重定向"><a href="#重定向" class="headerlink" title="重定向"></a>重定向</h3><p>在http的server上加如下代码:</p><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk">return <span class="hljs-number">301</span> https:<span class="hljs-regexp">//</span><span class="hljs-variable">$server_name</span><span class="hljs-variable">$request_url</span><br></code></pre></td></tr></table></figure><h1 id="虚拟主机"><a href="#虚拟主机" class="headerlink" title="虚拟主机"></a>虚拟主机</h1><p>虚拟主机可以在一台服务器上部署多个站点,nginx的虚拟主机是通过server块来实现的,每个server块就是一个虚拟主机,通过server_name来指定这个虚拟主机的域名。</p>]]></content>
<summary type="html">常用的用于设置代理的工具,同类的有使用Golang写的更轻量一点的Caddy。</summary>
<category term="技术栈" scheme="http://example.com/categories/%E6%8A%80%E6%9C%AF%E6%A0%88/"/>
<category term="前端" scheme="http://example.com/tags/%E5%89%8D%E7%AB%AF/"/>
<category term="笔记" scheme="http://example.com/tags/%E7%AC%94%E8%AE%B0/"/>
<category term="服务器" scheme="http://example.com/tags/%E6%9C%8D%E5%8A%A1%E5%99%A8/"/>
</entry>
<entry>
<title>Problem</title>
<link href="http://example.com/2024/01/30/Problem/"/>
<id>http://example.com/2024/01/30/Problem/</id>
<published>2024-01-30T12:05:30.000Z</published>
<updated>2024-08-15T09:26:22.683Z</updated>
<content type="html"><![CDATA[<h1 id="Git-gt-Time-out"><a href="#Git-gt-Time-out" class="headerlink" title="Git -> Time out"></a>Git -> Time out</h1><ul><li><p>背景:</p><p>用于解决git上传Time out的情况。<br>无论是用git的push还是hexo的deploy,经常会出现Time out的情况。</p></li><li><p>解决方法一:</p><p>重启+开开关关梯子+更换网络</p><blockquote><p>这个的话完全看玄学,我之前经常开开关关梯子+换网就解决了,很抽象。</p></blockquote></li><li><p>解决方法二:</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs stylus">git config <span class="hljs-attr">--global</span> https<span class="hljs-selector-class">.proxy</span> <span class="hljs-comment">//使用代理</span><br>git config <span class="hljs-attr">--global</span> <span class="hljs-attr">--unset</span> https<span class="hljs-selector-class">.proxy</span> <span class="hljs-comment">//取消代理</span><br></code></pre></td></tr></table></figure><blockquote><p>这个我用过很多很多很多很多次,都把他背下来了,有时候确实有用</p></blockquote></li><li><p>解决方法三:</p><p>在传TS笔记的时候家里的网死活传不上去,尝试过网上所有的方法了整了一下午,很抽象的是可以去外网。</p><p>那不妨直接用git自己内置的update flies,即拖动上传。</p></li></ul><h1 id="TypeScript-gt-“Could-not-find-a-declaration-file-for-module-‘xxx-js’-‘xxx-js’-implicitly-has-an-‘any’-type"><a href="#TypeScript-gt-“Could-not-find-a-declaration-file-for-module-‘xxx-js’-‘xxx-js’-implicitly-has-an-‘any’-type" class="headerlink" title="TypeScript -> “Could not find a declaration file for module ‘xxx.js’. ‘xxx.js’ implicitly has an ‘any’ type."></a>TypeScript -> “Could not find a declaration file for module ‘xxx.js’. ‘xxx.js’ implicitly has an ‘any’ type.</h1><ul><li><p>背景:</p><p>尝试使用TS的时候呢,遇到了一些问题,在main.ts中引用已经写好的js文件时(旧版本已经写好的配置文件,详见blog中的vue.config)发生报错,错误代码为ts(7016),一眼ts和原生起冲突了。</p></li><li><p>解决方法一:</p><p>我没试过这个方法,但是Vue2的可以试试(也许)。</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">//将import引入改为require引入</span><br><span class="hljs-keyword">import</span> <span class="hljs-variable language_">module</span> <span class="hljs-keyword">from</span> <span class="hljs-string">"module.js"</span><br><span class="hljs-comment">//改为=></span><br><span class="hljs-keyword">const</span> <span class="hljs-variable language_">module</span> = <span class="hljs-built_in">require</span>(<span class="hljs-string">'module.js'</span>)<br></code></pre></td></tr></table></figure><p>为啥我没试过呢,因为在Vue3中,require语法已经不能使用了,在Vue3版本中,直接使用上述的require语法会导致报错,提示require不是一个函数。这是因为Vue3及以上版本使用了ES Module语法,不再支持使用CommonJS语法来引入模块。</p><blockquote><p>小知识:require和import的性能比较</p><p><code>require</code> 的性能相对于 <code>import</code> 稍低。</p><p>因为 <code>require</code> 是在运行时才引入模块并且还赋值给某个变量,而 <code>import</code> 只需要依据 <code>import</code> 中的接口在编译时引入指定模块所以性能稍高</p></blockquote></li><li><p>解决方法二:</p><p>也是我自己琢磨出来的方法,适用性比较低吧可能。</p><p>问题既然出在 TS 和 JS 对接上,那我向上兼容,把 JS 文件更新成 TS 的不就完事了,在修改引用的文件后缀和文件内容后果然还是不报错了。</p></li><li><p>解决方法三:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">//先在项目目录(也就是和众多config同目录)下创建一个modules.d.ts</span><br><span class="hljs-comment">//modules.d.ts (modules可以自己取名字)</span><br><span class="hljs-keyword">declare</span> <span class="hljs-variable language_">module</span> <span class="hljs-string">'*.js'</span>;<br><br><span class="hljs-comment">//然后在 tsconfig.json 中的 "include" 配置下添加一个 "modules.d.ts"</span><br><span class="hljs-comment">// tsconfig.json</span><br><span class="hljs-string">"include"</span>: [<span class="hljs-string">"src/**/*.ts"</span>, <span class="hljs-string">"src/**/*.tsx"</span>, <span class="hljs-string">"src/**/*.vue"</span>, <span class="hljs-string">"module.d.ts"</span>]<br><br><span class="hljs-comment">//然后在你的main.ts中用正常的import xx from 'xx.js' 即可</span><br><span class="hljs-comment">//main.ts</span><br><span class="hljs-keyword">import</span> xxx <span class="hljs-keyword">from</span> <span class="hljs-string">'xx.js'</span><br></code></pre></td></tr></table></figure><p>推荐使用的方法,无论是你自己的Js文件还是引的依赖包都可以从这里引入到main.ts中,如果引依赖。</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">//modules.d.ts</span><br><span class="hljs-keyword">declare</span> <span class="hljs-variable language_">module</span> <span class="hljs-string">'依赖名'</span>;<br><br><span class="hljs-comment">//main.ts</span><br><span class="hljs-keyword">import</span> xxx <span class="hljs-keyword">from</span> <span class="hljs-string">'依赖名'</span><br></code></pre></td></tr></table></figure></li></ul><h1 id="TypeScript-gt-代码未错误但出现错误提醒(编辑器为vscode)"><a href="#TypeScript-gt-代码未错误但出现错误提醒(编辑器为vscode)" class="headerlink" title="TypeScript -> 代码未错误但出现错误提醒(编辑器为vscode)"></a>TypeScript -> 代码未错误但出现错误提醒(编辑器为vscode)</h1><ul><li><p>背景:</p><p>在写TS项目的时候发现出了报错提示,但是我是直接粘的element-plus的代码,报的错也很奇怪,网上搜也解决不彻底,最抽象的是项目能跑。</p></li></ul><blockquote><p> 后面才知道是因为eslint(vscode扩展-用于检查js书写错误)</p></blockquote><p>遂去找ts检查扩展,发现根本找不到。</p><blockquote><p>好像目前就没有好用的ts语法检查扩展</p></blockquote><ul><li><p>解决方法一:</p><p>首先这个方法我是行不通的,但是我觉得可能是我某个扩展的问题。</p><p>打开设置 -> 搜索validate ->下面找到并设置禁止typescript验证 -> 重新启动编辑器。</p></li><li><p>解决方法二:</p><p>直接让他不检查语法错误。</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript">在script标签下加上这行注释。注意,是注释!!<br><br><span class="hljs-comment">// @ts-nocheck</span><br></code></pre></td></tr></table></figure><p>这样ts代码就不会报错了,但也检查不出来问题了,至少不难受了看着。</p></li><li><p>解决方法三:</p><p>没有三了,按道理来说网上是有某种关于eslint配置可行的,但是我配了两个都不行。我以后找到了再来更新吧🤕</p></li></ul><h1 id="IPv4-amp-IPv6-gt-“http-proxy-error”"><a href="#IPv4-amp-IPv6-gt-“http-proxy-error”" class="headerlink" title="IPv4&IPv6 -> “http proxy error”"></a>IPv4&IPv6 -> “http proxy error”</h1><p>之前在打ICT的时候就遇到过类似的问题,当时以为是es6的fetch哪里没配置好,后面换成axios就可以了,但实际不是这样。今天在打服创的时候又遇到这玩意了。</p><ul><li><p>背景</p><p>跨域,localhost但是不同端口跨域。</p><p>我前端config文件明明配置得好好的,但是f12永远报我接的是前端跑着的端口,代码编辑器上更是出一个http proxy error,我就对着一直改啊改啊,发现一直还是这个报错,后面找到是后端的问题。</p></li><li><p>解决方法:</p><p>我遇到的问题实际上是后端允许的网络协议和前端发出来的网络协议不同,用的python后端,那边是给的一个IPv4接口,前端用的是IPv6,结果接不上,解决方法就是更改后端接口使用的网络协议。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment">#此处就放后端部分代码了,语言是python</span><br><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:<br> app.run(host = <span class="hljs-string">'0.0.0.0'</span>,port = <span class="hljs-number">5000</span>)<br> <span class="hljs-comment">#在本地的端口5000运行,配置IPv4 IPv6都可以使用,不然前端报错http proxy error</span><br></code></pre></td></tr></table></figure></li></ul><h1 id="Headers-gt-400-Bad-REQUEST-文件上传"><a href="#Headers-gt-400-Bad-REQUEST-文件上传" class="headerlink" title="Headers -> 400(Bad REQUEST)文件上传"></a>Headers -> 400(Bad REQUEST)<code>文件上传</code></h1><ul><li><p>背景:</p><p>是需要上传一个文件,又是经典的Postman可以前端不行。</p></li><li><p>解决方法:</p><p>最后发现是Headers的问题,大家都说:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-attr">headers</span>: {<br> <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'multipart/form-data'</span><br> }<br></code></pre></td></tr></table></figure><p>上传文件要这样子配置,但是实际上我把它整个headers删了反而成功了,原因是什么呢?</p><blockquote><p>发现去掉 Content-Type 的请求头部多了一个 boundary ,查查。</p><p><strong>Boundary 是一种用于分隔多个实体(如文件、表单字段等)的标识符</strong>。 它通常用于 multipart/form-data 类型的请求中,用于将多个部分组合在一起,并指示它们的边界。</p></blockquote><p>原来<code>POST</code>请求上传文件的时候是不需要自己设置 Content-Type,会自动给你添加一个 boundary ,用来分割消息主体中的每个字段,如果这个时候自己设置了 Content-Type, 服务器反而不知道怎么分割各个字段。</p></li></ul><h1 id="Javascript-amp-CSS-gt-label点击事件阻止"><a href="#Javascript-amp-CSS-gt-label点击事件阻止" class="headerlink" title="Javascript&CSS -> label点击事件阻止"></a>Javascript&CSS -> label点击事件阻止</h1><ul><li><p>背景:</p><p>以下HTML:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">label</span>></span><br><span class="hljs-tag"><<span class="hljs-name">div</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"console.log(1)"</span>></span><span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><span class="hljs-tag"></<span class="hljs-name">label</span>></span><br></code></pre></td></tr></table></figure><p>怎么才能实现点击div但是不触发label的点击事件呢?我找了很多方法CSS的还有JS的都不太行,CSS的话是想hover到div上时label的点击事件取消,但是又会连带到div里,用div包label和div加absolute又很麻烦因为还有别的需求。JS是想使用stopPropagation阻止冒泡,但是label的点击事件不受影响。</p></li><li><p>解决方法:</p><p>改成这个结构:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">div</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"inputFocus"</span>></span><br><span class="hljs-tag"><<span class="hljs-name">div</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"stopFocus()"</span>></span><span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"inputRef"</span>></span><br></code></pre></td></tr></table></figure><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">const</span> <span class="hljs-title function_">inputFocus</span> = (<span class="hljs-params"></span>) => {<br> inputRef.<span class="hljs-property">value</span>.<span class="hljs-title function_">click</span>();<br>}<br><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">stopFocus</span> = (<span class="hljs-params">event</span>) => {<br> <span class="hljs-comment">//业务函数</span><br> ...<br> <span class="hljs-comment">//阻止冒泡</span><br> <span class="hljs-variable language_">window</span>.<span class="hljs-property">event</span>.<span class="hljs-title function_">stopPropagation</span>();<br>}<br></code></pre></td></tr></table></figure><p>这样就行了div是可以使用stopPropagation函数的。</p><blockquote><p>但是为什么label不行呢,全网查找了一下没找到。</p><p>去MDN看了一下对于这个标签的描述:</p><p>不要在 <code>label</code> 元素内部放置可交互的元素,这样做会让用户更难激活/触发与 <code>label</code> 相关联的表单输入元素。</p></blockquote></li></ul><h1 id="HTML-amp-Javascript-gt-“input标签使用”"><a href="#HTML-amp-Javascript-gt-“input标签使用”" class="headerlink" title="HTML&Javascript -> “input标签使用”"></a>HTML&Javascript -> “input标签使用”</h1><ul><li><p>背景:</p><p>需求是上传图片、显示、点icon删除、点icon预览。</p><p>但是卡在删除上面了,有一个小bug——每次点击icon删除后就会没办法上传之前上传的那一张图片。</p></li><li><p>解决方法:</p><p>其实很简单只不过说我把input标签隐藏起来了,每次删除都是把显示的图片删掉,原本传到input里图片的没删掉。</p><p>但为什么还要写到Problem中呢?</p><p>因为我发现input里图片删除也很有意思:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs vue"><template><br><input ref="inputRef"><br></template><br><script><br> const inputRef = ref('')<br> //inputRef.value 对应的是他的页面标签<br> //inputRef.value.value 对应的是他的图片(路径)<br></script><br></code></pre></td></tr></table></figure></li></ul><h1 id="Vue-gt-“addEventListener-is-not-a-function”"><a href="#Vue-gt-“addEventListener-is-not-a-function”" class="headerlink" title="Vue -> “addEventListener is not a function”"></a>Vue -> “addEventListener is not a function”</h1><ul><li><p>背景:</p><p>在引一个3d canvas库,但是一直报这个错误,后面找到是vue的ref问题,其实报这个错误是因为一直都获取不到标签。</p></li><li><p>解决方法:</p><p>添加onMounted函数,是这样的:</p><ul><li>Vue 会首先解析和执行组件中的 <code><script></code> 部分,这包括响应式数据、计算属性、监听器、方法等的定义。</li><li>接着会编译模板,将数据绑定到视图中,渲染生成的 HTML。这一步通常是在<code>beforeCreate</code> 和 <code>created</code> 阶段中完成,因为 Vue 需要在渲染之前准备好数据、计算属性等。</li><li><code>onMounted</code> 生命周期钩子函数是在 Vue 3 中的 Composition API 中使用的,它在组件挂载到 DOM 后执行。在 Vue 3 的生命周期中,类似于 <code>onMounted</code> 的生命周期钩子函数会在合适的时机被调用。这意味着它在组件渲染后执行。</li></ul><p>因为定义的ref在script中还未访问到DOM元素,就自然还为空,为空的话后续函数就没办法执行咯。</p></li></ul><h1 id="MITT-gt-onAPI使用问题"><a href="#MITT-gt-onAPI使用问题" class="headerlink" title="MITT -> onAPI使用问题"></a>MITT -> onAPI使用问题</h1><ul><li><p>背景:</p><p>在兄弟组件中调用全局事件总线MITT的时候,emit和on都是可以使用的,但是:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">const</span> test = <span class="hljs-title function_">ref</span>()<br>event.<span class="hljs-title function_">on</span>(<span class="hljs-string">'name'</span>,<span class="hljs-function">(<span class="hljs-params">val</span>)=></span>{<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(val);<span class="hljs-comment">//可以得到值</span><br> test.<span class="hljs-property">value</span> = val;<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(test.<span class="hljs-property">value</span>);<span class="hljs-comment">//可以得到值</span><br>})<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(test.<span class="hljs-property">value</span>);<span class="hljs-comment">//不可以得到值</span><br></code></pre></td></tr></table></figure><p>这就很抽象了,那我调用on的意义不久完全失去了嘛。</p><p>经过尝试ref -> reactive、生命周期等等都没用。</p><p>讨论了一下能看出是渲染顺序问题或者深拷贝问题,但是就是不知道怎么解决。</p></li><li><p>解决方法一:</p><p>最原始的方法就是存到localstorage里面🤣。</p></li><li><p>解决方法二:</p><p>换用pinia Vue状态管理库。</p></li><li><p>解决方法三:</p><p>先用emit传到父组件中,然后再用defineprops传到目的组件中。</p></li></ul><h1 id="HTML-amp-CSS-gt-fixed状态盒子消失"><a href="#HTML-amp-CSS-gt-fixed状态盒子消失" class="headerlink" title="HTML&CSS -> fixed状态盒子消失"></a>HTML&CSS -> fixed状态盒子消失</h1><ul><li><p>背景:</p><p>Header盒子加了一个fixed样式,但是不见了。</p></li><li><p>解决方法:</p><p>加一下z-index。</p></li></ul><h1 id="Pack-gt-打包的时候index-html无法打开"><a href="#Pack-gt-打包的时候index-html无法打开" class="headerlink" title="Pack -> 打包的时候index.html无法打开"></a>Pack -> 打包的时候index.html无法打开</h1><ul><li><p>背景:</p><p>需要把写好的文件给队友调试,但是发现index.html无法打开。</p></li><li><p>解决方法:</p><p>在vite.config.js下:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//添加如下代码</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title function_">defineConfig</span>({<br> <span class="hljs-attr">plugins</span>: [<span class="hljs-title function_">vue</span>()],<br> <span class="hljs-attr">base</span>:<span class="hljs-string">'./'</span><br>})<br></code></pre></td></tr></table></figure><p>然后index.html不要直接打开,会有跨域问题,使用vscode 的<code>Live Server</code>插件打开。</p></li></ul><h1 id="CSS-gt-高度非固定造成的样式错误"><a href="#CSS-gt-高度非固定造成的样式错误" class="headerlink" title="CSS -> 高度非固定造成的样式错误"></a>CSS -> 高度非固定造成的样式错误</h1><ul><li><p>背景:</p><p>比如一个for循环渲染div,然后造成的高度比预设值多,那就会多出来一些白色的。</p></li><li><p>解决方法:</p><p>可以包两层div,外层heightauto,内层height100vh,然后在写。</p></li></ul><h1 id="文件传输-gt-发送文件服务器报500"><a href="#文件传输-gt-发送文件服务器报500" class="headerlink" title="文件传输 -> 发送文件服务器报500"></a>文件传输 -> 发送文件服务器报500</h1><ul><li><p>背景:</p><p>在打比赛的时候发送为JSON格式的文件不行,服务器报500,Postman也不行</p></li><li><p>解决方法:</p><p>JSON的key设置为files。</p></li></ul><h1 id="服务器搭建-gt-如何快速开始搭建一个服务器"><a href="#服务器搭建-gt-如何快速开始搭建一个服务器" class="headerlink" title="服务器搭建 -> 如何快速开始搭建一个服务器"></a>服务器搭建 -> 如何快速开始搭建一个服务器</h1><p>还不是很熟悉服务器相关的操作,所以写一下拿到一个新的服务器相关的操作。</p><p>先进root,拿到最高权限。</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">sudo passwd root<br></code></pre></td></tr></table></figure><p>输入两次密码(密码是看不到的,但是其实已经输入了)</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">su<br></code></pre></td></tr></table></figure><p>再输入两次密码。</p><p>下载apt-get:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">sudo apt-get install ssh<br></code></pre></td></tr></table></figure><p>下载nginx,同时检查nginx版本以及启动一下nginx:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs shell">apt-get install nginx<br>nginx -v<br>service nginx start<br></code></pre></td></tr></table></figure><p>之后进入浏览器,在Ubuntu系统中输入<code>127.0.0.1</code>,在其他电脑中输入<code>该服务器的ip地址</code>即可访问。</p><p>在<code>/var/www/html</code>目录下:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">sudo git clone <repoName><br></code></pre></td></tr></table></figure><p>然后调整配置:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">sudo nano /etc/nginx/sites-enabled/default<br></code></pre></td></tr></table></figure><p>把<code>server->root</code>重写为新clone的目录下。</p><p>重新启动nginx:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs shell">sudo nginx -t<br>sudo systemctl restart nginx<br></code></pre></td></tr></table></figure><h1 id="服务器搭建-gt-如何部署SSL证书"><a href="#服务器搭建-gt-如何部署SSL证书" class="headerlink" title="服务器搭建 -> 如何部署SSL证书"></a>服务器搭建 -> 如何部署SSL证书</h1><p>经过备案,获取到SSL证书之后,下载到本地。</p><p>先通过ssh传文件到服务器:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">ssh root@<ip><br></code></pre></td></tr></table></figure><p>然后传文件,将证书文件传到nginx安装目录下(默认/etc/nginx):</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">scp -r <上传文件目录地址> root@<ip>:<服务器安放地址><br></code></pre></td></tr></table></figure><p>然后配置nginx:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><code class="hljs shell"><span class="hljs-meta prompt_">#</span><span class="language-bash">将端口设置为443</span><br>sudo nano /etc/nginx/sites-enabled/default<br><span class="hljs-meta prompt_"></span><br><span class="hljs-meta prompt_">#</span><span class="language-bash">修改配置</span><br>sudo nano /etc/nginx/nginx.conf<br><span class="hljs-meta prompt_"></span><br><span class="hljs-meta prompt_">#</span><span class="language-bash">在http间添加</span><br>server {<br> #SSL 默认访问端口号为 443<br> listen 443 ssl default; <br> #请填写绑定证书的域名<br> server_name <>; <br> #请填写证书文件的相对路径或绝对路径<br> ssl_certificate xxx.crt; <br> #请填写私钥文件的相对路径或绝对路径<br> ssl_certificate_key xxx.key; <br> ssl_session_timeout 5m;<br> #请按照以下协议配置<br> ssl_protocols TLSv1.2 TLSv1.3; <br> #请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。<br> ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; <br> ssl_prefer_server_ciphers on;<br> location / {<br> #网站主页路径。此路径仅供参考,具体请您按照实际目录操作。<br> #例如,您的网站主页在 Nginx 服务器的 /etc/www 目录下,则请修改 root 后面的 html 为 /etc/www。<br> root html; <br> index index.html index.htm;<br> }<br> }<br></code></pre></td></tr></table></figure><p>再运行一次</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs shell">nginx -t<br>nginx -s reload<br></code></pre></td></tr></table></figure>]]></content>
<summary type="html">这里是一些我遇到的问题集合</summary>
<category term="随笔" scheme="http://example.com/categories/%E9%9A%8F%E7%AC%94/"/>
<category term="😶🌫️" scheme="http://example.com/tags/%F0%9F%98%B6%E2%80%8D%F0%9F%8C%AB%EF%B8%8F/"/>
</entry>
<entry>
<title>TypeScript</title>
<link href="http://example.com/2024/01/30/TypeScript/"/>
<id>http://example.com/2024/01/30/TypeScript/</id>
<published>2024-01-30T04:17:40.000Z</published>
<updated>2024-03-09T07:01:30.311Z</updated>
<content type="html"><![CDATA[<h1 id="TypeScript"><a href="#TypeScript" class="headerlink" title="TypeScript"></a>TypeScript</h1><p>前言:很久之前就想着学Typescript了,但是一直在嘴上说没有时间学,说是没有但实际上学习这个也不会花费太久时间,只要肯挤时间并强制去完成就肯定可以完成。</p><p><a href="https://typescript.bootcss.com/">TypeScript 中文手册 </a></p><p>TS其实就是JS Plus,笔记中只写我觉得和JS不一样的很多的地方详细需要自己参考文档。</p><h1 id="TypeScript相比JS的优势"><a href="#TypeScript相比JS的优势" class="headerlink" title="TypeScript相比JS的优势"></a>TypeScript相比JS的优势</h1><ul><li>更早(写代码的同时)发现错误,减少找Bug、改Bug时间,提升开发效率。</li><li>程序中任何位置的代码都有代码提示,随时随地的安全感,增强了开发体验。</li><li>强大的类型系统提升了代码的可维护性,使得重构代码更加容易。</li><li>支持最新的ECMAScript语法,优先体验最新的语法,让你走在前端技术的最前沿。</li><li>TS类型推断机制,不需要在代码中的每个地方都显示标注类型,让你在享受优势的同时,尽量降低了成本。除此之外,Vue 3源码使用TS重写、Angular默认支持TS、React与TS完美配合,TypeScript已成为大中型前端项目的首先编程语言。</li></ul><h1 id="安装TypeScript"><a href="#安装TypeScript" class="headerlink" title="安装TypeScript"></a>安装TypeScript</h1><p>有两种主要的方式来获取TypeScript工具:</p><ul><li>通过npm(Node.js包管理器)</li><li>安装Visual Studio的TypeScript插件</li></ul><p>Visual Studio 2017和Visual Studio 2015 Update 3默认包含了TypeScript。 如果你的Visual Studio还没有安装TypeScript,你可以<a href="https://typescript.bootcss.com/index.html#download-links">下载</a>它。</p><p>针对使用npm的用户:</p><figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmake">npm <span class="hljs-keyword">install</span> -g typescript<br></code></pre></td></tr></table></figure><h1 id="TS中的高级功能"><a href="#TS中的高级功能" class="headerlink" title="TS中的高级功能"></a>TS中的高级功能</h1><h2 id="类型注解"><a href="#类型注解" class="headerlink" title="类型注解"></a>类型注解</h2><p>TypeScript里的类型注解是一种轻量级的为函数或变量添加约束的方式。 在这个例子里,我们希望<code>greeter</code>函数接收一个字符串参数。 然后尝试把<code>greeter</code>的调用改成传入一个数组:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">greeter</span>(<span class="hljs-params">person: <span class="hljs-built_in">string</span></span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-string">"Hello, "</span> + person;<br>}<br><br><span class="hljs-keyword">let</span> user = [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>]; <br><br><span class="hljs-variable language_">document</span>.<span class="hljs-property">body</span>.<span class="hljs-property">innerHTML</span> = <span class="hljs-title function_">greeter</span>(user);<br></code></pre></td></tr></table></figure><p>重新编译,你会看到产生了一个错误。</p><figure class="highlight subunit"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs subunit"><span class="hljs-keyword">error </span>TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string'.<br></code></pre></td></tr></table></figure><p>类似地,尝试删除<code>greeter</code>调用的所有参数。 TypeScript会告诉你使用了非期望个数的参数调用了这个函数。 在这两种情况中,TypeScript提供了静态的代码分析,它可以分析代码结构和提供的类型注解。</p><p><strong>要注意的是尽管有错误,<code>greeter.js</code>文件还是被创建了。 就算你的代码里有错误,你仍然可以使用TypeScript。但在这种情况下,TypeScript会警告你代码可能不会按预期执行。</strong></p><h2 id="接口"><a href="#接口" class="headerlink" title="接口"></a>接口</h2><p>让我们开发这个示例应用。这里我们使用接口来描述一个拥有<code>firstName</code>和<code>lastName</code>字段的对象。 在TypeScript里,只在两个类型内部的结构兼容那么这两个类型就是兼容的。 这就允许我们在实现接口时候只要保证包含了接口要求的结构就可以,而不必明确地使用<code>implements</code>语句。</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Person</span> {<br> <span class="hljs-attr">firstName</span>: <span class="hljs-built_in">string</span>;<br> <span class="hljs-attr">lastName</span>: <span class="hljs-built_in">string</span>;<br>}<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">greeter</span>(<span class="hljs-params">person: Person</span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-string">"Hello, "</span> + person.<span class="hljs-property">firstName</span> + <span class="hljs-string">" "</span> + person.<span class="hljs-property">lastName</span>;<br>}<br><br><span class="hljs-keyword">let</span> user = { <span class="hljs-attr">firstName</span>: <span class="hljs-string">"Jane"</span>, <span class="hljs-attr">lastName</span>: <span class="hljs-string">"User"</span> };<br><br><span class="hljs-variable language_">document</span>.<span class="hljs-property">body</span>.<span class="hljs-property">innerHTML</span> = <span class="hljs-title function_">greeter</span>(user);<br></code></pre></td></tr></table></figure><p>因为我对type对象不是很了解(看完这些文章之后感觉到tasklist有些语句需要规范化了orz),这里也补充一下type&interface的知识:</p><p>类型别名 type 和 接口 interface 区别与联系</p><ul><li><p>不同点:</p><ul><li><p>类型别名type用来给一个类型起个新名字,接口interface是命名数据结构(例如对象)的另一种方式</p></li><li><p>type可以用来表示基本类型、对象类型、联合类型、元组和交集;interface仅限于描述对象类型</p></li><li><p>interface 定义重名了会合并属性,type 会报错</p></li><li><p>interface 可以 extends, type 是不允许 extends ,但是 type 缺可以通过交叉类型 实现 interface 的 extend 行为,并且两者并不是相互独立的,也就是说 interface 可以 extends type, type 也可以 与 interface 类型 交叉</p></li></ul></li><li><p>相同点:</p><ul><li><p>都可以描述 Object和Function</p></li><li><p>interface 和 type 都可以继承。</p></li></ul></li></ul><h2 id="类"><a href="#类" class="headerlink" title="类"></a>类</h2><p>最后,让我们使用类来改写这个例子。 TypeScript支持JavaScript的新特性,比如支持基于类的面向对象编程。</p><p>让我们创建一个<code>Student</code>类,它带有一个构造函数和一些公共字段。 注意类和接口可以一起共作,程序员可以自行决定抽象的级别。</p><p>还要注意的是,在构造函数的参数上使用<code>public</code>等同于创建了同名的成员变量。</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Student</span> {<br> <span class="hljs-attr">fullName</span>: <span class="hljs-built_in">string</span>;<br> <span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">public</span> firstName: <span class="hljs-built_in">string</span>, <span class="hljs-keyword">public</span> middleInitial: <span class="hljs-built_in">string</span>, <span class="hljs-keyword">public</span> lastName: <span class="hljs-built_in">string</span></span>) {<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">fullName</span> = firstName + <span class="hljs-string">" "</span> + middleInitial + <span class="hljs-string">" "</span> + lastName;<br> }<br>}<br><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Person</span> {<br> <span class="hljs-attr">firstName</span>: <span class="hljs-built_in">string</span>;<br> <span class="hljs-attr">lastName</span>: <span class="hljs-built_in">string</span>;<br>}<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">greeter</span>(<span class="hljs-params">person : Person</span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-string">"Hello, "</span> + person.<span class="hljs-property">firstName</span> + <span class="hljs-string">" "</span> + person.<span class="hljs-property">lastName</span>;<br>}<br><br><span class="hljs-keyword">let</span> user = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Student</span>(<span class="hljs-string">"Jane"</span>, <span class="hljs-string">"M."</span>, <span class="hljs-string">"User"</span>);<br><br><span class="hljs-variable language_">document</span>.<span class="hljs-property">body</span>.<span class="hljs-property">innerHTML</span> = <span class="hljs-title function_">greeter</span>(user);<br></code></pre></td></tr></table></figure><h1 id="基础类型"><a href="#基础类型" class="headerlink" title="基础类型"></a>基础类型</h1><h2 id="枚举"><a href="#枚举" class="headerlink" title="枚举"></a>枚举</h2><p><code>enum</code>类型是对JavaScript标准数据类型的一个补充。 像C#等其它语言一样,使用枚举类型可以为一组数值赋予友好的名字。</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">enum</span> <span class="hljs-title class_">Color</span> {<span class="hljs-title class_">Red</span>, <span class="hljs-title class_">Green</span>, <span class="hljs-title class_">Blue</span>}<br><span class="hljs-keyword">let</span> <span class="hljs-attr">c</span>: <span class="hljs-title class_">Color</span> = <span class="hljs-title class_">Color</span>.<span class="hljs-property">Green</span>;<br></code></pre></td></tr></table></figure><p>默认情况下,从<code>0</code>开始为元素编号。 你也可以手动的指定成员的数值。 例如,我们将上面的例子改成从<code>1</code>开始编号:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">enum</span> <span class="hljs-title class_">Color</span> {<span class="hljs-title class_">Red</span> = <span class="hljs-number">1</span>, <span class="hljs-title class_">Green</span>, <span class="hljs-title class_">Blue</span>}<br><span class="hljs-keyword">let</span> <span class="hljs-attr">c</span>: <span class="hljs-title class_">Color</span> = <span class="hljs-title class_">Color</span>.<span class="hljs-property">Green</span>;<br></code></pre></td></tr></table></figure><p>或者,全部都采用手动赋值:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">enum</span> <span class="hljs-title class_">Color</span> {<span class="hljs-title class_">Red</span> = <span class="hljs-number">1</span>, <span class="hljs-title class_">Green</span> = <span class="hljs-number">2</span>, <span class="hljs-title class_">Blue</span> = <span class="hljs-number">4</span>}<br><span class="hljs-keyword">let</span> <span class="hljs-attr">c</span>: <span class="hljs-title class_">Color</span> = <span class="hljs-title class_">Color</span>.<span class="hljs-property">Green</span>;<br></code></pre></td></tr></table></figure><p>枚举类型提供的一个便利是你可以由枚举的值得到它的名字。 例如,我们知道数值为2,但是不确定它映射到Color里的哪个名字,我们可以查找相应的名字:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">enum</span> <span class="hljs-title class_">Color</span> {<span class="hljs-title class_">Red</span> = <span class="hljs-number">1</span>, <span class="hljs-title class_">Green</span>, <span class="hljs-title class_">Blue</span>}<br><span class="hljs-keyword">let</span> <span class="hljs-attr">colorName</span>: <span class="hljs-built_in">string</span> = <span class="hljs-title class_">Color</span>[<span class="hljs-number">2</span>];<br><br><span class="hljs-title function_">alert</span>(colorName); <span class="hljs-comment">// 显示'Green'因为上面代码里它的值是2</span><br></code></pre></td></tr></table></figure><h2 id="任意值"><a href="#任意值" class="headerlink" title="任意值"></a>任意值</h2><p>有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型。 这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。 这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。 那么我们可以使用<code>any</code>类型来标记这些变量</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> <span class="hljs-attr">list</span>: <span class="hljs-built_in">any</span>[] = [<span class="hljs-number">1</span>, <span class="hljs-literal">true</span>, <span class="hljs-string">"free"</span>];<br></code></pre></td></tr></table></figure><h2 id="Never"><a href="#Never" class="headerlink" title="Never"></a>Never</h2><p><code>never</code>类型表示的是那些永不存在的值的类型。 例如,<code>never</code>类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 变量也可能是<code>never</code>类型,当它们被永不为真的类型保护所约束时。</p><p><code>never</code>类型是任何类型的子类型,也可以赋值给任何类型;然而,<em>没有</em>类型是<code>never</code>的子类型或可以赋值给<code>never</code>类型(除了<code>never</code>本身之外)。 即使<code>any</code>也不可以赋值给<code>never</code>。</p><p>下面是一些返回<code>never</code>类型的函数:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 返回never的函数必须存在无法达到的终点</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">error</span>(<span class="hljs-params">message: <span class="hljs-built_in">string</span></span>): <span class="hljs-built_in">never</span> {<br> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(message);<br>}<br><br><span class="hljs-comment">// 推断的返回值类型为never</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">fail</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-title function_">error</span>(<span class="hljs-string">"Something failed"</span>);<br>}<br><br><span class="hljs-comment">// 返回never的函数必须存在无法达到的终点</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">infiniteLoop</span>(<span class="hljs-params"></span>): <span class="hljs-built_in">never</span> {<br> <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {<br> }<br>}<br></code></pre></td></tr></table></figure><h2 id="类型断言"><a href="#类型断言" class="headerlink" title="类型断言"></a>类型断言</h2><p>有时候你会遇到这样的情况,你会比TypeScript更了解某个值的详细信息。 通常这会发生在你清楚地知道一个实体具有比它现有类型更确切的类型。</p><p>通过<em>类型断言</em>这种方式可以告诉编译器,“相信我,我知道自己在干什么”。 类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起作用。 TypeScript会假设你,程序员,已经进行了必须的检查。</p><p>类型断言有两种形式。 其一是“尖括号”语法:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> <span class="hljs-attr">someValue</span>: <span class="hljs-built_in">any</span> = <span class="hljs-string">"this is a string"</span>;<br><br><span class="hljs-keyword">let</span> <span class="hljs-attr">strLength</span>: <span class="hljs-built_in">number</span> = (<<span class="hljs-built_in">string</span>>someValue).<span class="hljs-property">length</span>;<br></code></pre></td></tr></table></figure><p>另一个为<code>as</code>语法:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> <span class="hljs-attr">someValue</span>: <span class="hljs-built_in">any</span> = <span class="hljs-string">"this is a string"</span>;<br><br><span class="hljs-keyword">let</span> <span class="hljs-attr">strLength</span>: <span class="hljs-built_in">number</span> = (someValue <span class="hljs-keyword">as</span> <span class="hljs-built_in">string</span>).<span class="hljs-property">length</span>;<br></code></pre></td></tr></table></figure><p>两种形式是等价的。 至于使用哪个大多数情况下是凭个人喜好;然而,当你在TypeScript里使用JSX时,只有<code>as</code>语法断言是被允许的。</p><h1 id="变量声明"><a href="#变量声明" class="headerlink" title="变量声明"></a>变量声明</h1><p><code>let</code>和<code>const</code>是JavaScript里相对较新的变量声明方式。 像我们之前提到过的,<code>let</code>在很多方面与<code>var</code>是相似的,但是可以帮助大家避免在JavaScript里常见一些问题。 <code>const</code>是对<code>let</code>的一个增强,它能阻止对一个变量再次赋值。</p><p>因为TypeScript是JavaScript的超集,所以它本身就支持<code>let</code>和<code>const</code>。 下面我们会详细说明这些新的声明方式以及为什么推荐使用它们来代替<code>var</code>。</p><h2 id="作用域规则"><a href="#作用域规则" class="headerlink" title="作用域规则"></a>作用域规则</h2><p>对于熟悉其它语言的人来说,<code>var</code>声明有些奇怪的作用域规则。 看下面的例子:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">f</span>(<span class="hljs-params">shouldInitialize: <span class="hljs-built_in">boolean</span></span>) {<br> <span class="hljs-keyword">if</span> (shouldInitialize) {<br> <span class="hljs-keyword">var</span> x = <span class="hljs-number">10</span>;<br> }<br><br> <span class="hljs-keyword">return</span> x;<br>}<br><br><span class="hljs-title function_">f</span>(<span class="hljs-literal">true</span>); <span class="hljs-comment">// returns '10'</span><br><span class="hljs-title function_">f</span>(<span class="hljs-literal">false</span>); <span class="hljs-comment">// returns 'undefined'</span><br></code></pre></td></tr></table></figure><p>有些读者可能要多看几遍这个例子。 变量<code>x</code>是定义在*<code>if</code>语句里面<em>,但是我们却可以在语句的外面访问它。 这是因为<code>var</code>声明可以在包含它的函数,模块,命名空间或全局作用域内部任何位置被访问(我们后面会详细介绍),包含它的代码块对此没有什么影响。 有些人称此为</em><code>var</code>作用域<em>或</em>函数作用域*。 函数参数也使用函数作用域。</p><h2 id="变量获取怪异之处"><a href="#变量获取怪异之处" class="headerlink" title="变量获取怪异之处"></a>变量获取怪异之处</h2><p>快速的猜一下下面的代码会返回什么:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-number">10</span>; i++) {<br> <span class="hljs-built_in">setTimeout</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(i); }, <span class="hljs-number">100</span> * i);<br>}<br></code></pre></td></tr></table></figure><p>介绍一下,<code>setTimeout</code>会在若干毫秒的延时后执行一个函数(等待其它代码执行完毕)。</p><p>好吧,看一下结果:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-number">10</span><br><span class="hljs-number">10</span><br><span class="hljs-number">10</span><br><span class="hljs-number">10</span><br><span class="hljs-number">10</span><br><span class="hljs-number">10</span><br><span class="hljs-number">10</span><br><span class="hljs-number">10</span><br><span class="hljs-number">10</span><br><span class="hljs-number">10</span><br></code></pre></td></tr></table></figure><p>很多JavaScript程序员对这种行为已经很熟悉了,但如果你很不解,你并不是一个人。 大多数人期望输出结果是这样:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-number">0</span><br><span class="hljs-number">1</span><br><span class="hljs-number">2</span><br><span class="hljs-number">3</span><br><span class="hljs-number">4</span><br><span class="hljs-number">5</span><br><span class="hljs-number">6</span><br><span class="hljs-number">7</span><br><span class="hljs-number">8</span><br><span class="hljs-number">9</span><br></code></pre></td></tr></table></figure><p>还记得我们上面讲的变量获取吗?</p><blockquote><p>每当<code>g</code>被调用时,它都可以访问到<code>f</code>里的<code>a</code>变量。</p></blockquote><p>让我们花点时间考虑在这个上下文里的情况。 <code>setTimeout</code>在若干毫秒后执行一个函数,并且是在<code>for</code>循环结束后。 <code>for</code>循环结束后,<code>i</code>的值为<code>10</code>。 所以当函数被调用的时候,它会打印出<code>10</code>!</p><p>一个通常的解决方法是使用立即执行的函数表达式(IIFE)来捕获每次迭代时<code>i</code>的值:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-number">10</span>; i++) {<br> <span class="hljs-comment">// capture the current state of 'i'</span><br> <span class="hljs-comment">// by invoking a function with its current value</span><br> (<span class="hljs-keyword">function</span>(<span class="hljs-params">i</span>) {<br> <span class="hljs-built_in">setTimeout</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(i); }, <span class="hljs-number">100</span> * i);<br> })(i);<br>}<br></code></pre></td></tr></table></figure><p>这种奇怪的形式我们已经司空见惯了。 参数<code>i</code>会覆盖<code>for</code>循环里的<code>i</code>,但是因为我们起了同样的名字,所以我们不用怎么改<code>for</code>循环体里的代码。</p><h2 id="let声明"><a href="#let声明" class="headerlink" title="let声明"></a>let声明</h2><h3 id="块作用域"><a href="#块作用域" class="headerlink" title="块作用域"></a>块作用域</h3><p>当用<code>let</code>声明一个变量,它使用的是<em>词法作用域</em>或<em>块作用域</em>。 不同于使用<code>var</code>声明的变量那样可以在包含它们的函数外访问,块作用域变量在包含它们的块或<code>for</code>循环之外是不能访问的。</p><h3 id="重定义及屏蔽"><a href="#重定义及屏蔽" class="headerlink" title="重定义及屏蔽"></a>重定义及屏蔽</h3><p>我们提过使用<code>var</code>声明时,它不在乎你声明多少次;你只会得到1个。</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">f</span>(<span class="hljs-params">x</span>) {<br> <span class="hljs-keyword">var</span> x;<br> <span class="hljs-keyword">var</span> x;<br><br> <span class="hljs-keyword">if</span> (<span class="hljs-literal">true</span>) {<br> <span class="hljs-keyword">var</span> x;<br> }<br>}<br></code></pre></td></tr></table></figure><p>在上面的例子里,所有<code>x</code>的声明实际上都引用一个<em>相同</em>的<code>x</code>,并且这是完全有效的代码。 这经常会成为bug的来源。 好的是,<code>let</code>声明就不会这么宽松了。</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> x = <span class="hljs-number">10</span>;<br><span class="hljs-keyword">let</span> x = <span class="hljs-number">20</span>; <span class="hljs-comment">// 错误,不能在1个作用域里多次声明`x`</span><br></code></pre></td></tr></table></figure><p>并不是要求两个均是块级作用域的声明TypeScript才会给出一个错误的警告。</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">f</span>(<span class="hljs-params">x</span>) {<br> <span class="hljs-keyword">let</span> x = <span class="hljs-number">100</span>; <span class="hljs-comment">// error: interferes with parameter declaration</span><br>}<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">g</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-keyword">let</span> x = <span class="hljs-number">100</span>;<br> <span class="hljs-keyword">var</span> x = <span class="hljs-number">100</span>; <span class="hljs-comment">// error: can't have both declarations of 'x'</span><br>}<br></code></pre></td></tr></table></figure><p>并不是说块级作用域变量不能用函数作用域变量来声明。 而是块级作用域变量需要在明显不同的块里声明。</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">f</span>(<span class="hljs-params">condition, x</span>) {<br> <span class="hljs-keyword">if</span> (condition) {<br> <span class="hljs-keyword">let</span> x = <span class="hljs-number">100</span>;<br> <span class="hljs-keyword">return</span> x;<br> }<br><br> <span class="hljs-keyword">return</span> x;<br>}<br><br><span class="hljs-title function_">f</span>(<span class="hljs-literal">false</span>, <span class="hljs-number">0</span>); <span class="hljs-comment">// returns 0</span><br><span class="hljs-title function_">f</span>(<span class="hljs-literal">true</span>, <span class="hljs-number">0</span>); <span class="hljs-comment">// returns 100</span><br></code></pre></td></tr></table></figure><p>在一个嵌套作用域里引入一个新名字的行为称做<em>屏蔽</em>。 它是一把双刃剑,它可能会不小心地引入新问题,同时也可能会解决一些错误。 例如,假设我们现在用<code>let</code>重写之前的<code>sumMatrix</code>函数。</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">sumMatrix</span>(<span class="hljs-params">matrix: <span class="hljs-built_in">number</span>[][]</span>) {<br> <span class="hljs-keyword">let</span> sum = <span class="hljs-number">0</span>;<br> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i < matrix.<span class="hljs-property">length</span>; i++) {<br> <span class="hljs-keyword">var</span> currentRow = matrix[i];<br> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i < currentRow.<span class="hljs-property">length</span>; i++) {<br> sum += currentRow[i];<br> }<br> }<br><br> <span class="hljs-keyword">return</span> sum;<br>}<br></code></pre></td></tr></table></figure><p>这个版本的循环能得到正确的结果,因为内层循环的<code>i</code>可以屏蔽掉外层循环的<code>i</code>。</p><p><em>通常</em>来讲应该避免使用屏蔽,因为我们需要写出清晰的代码。 同时也有些场景适合利用它,你需要好好打算一下。</p><h2 id="let和const用哪个"><a href="#let和const用哪个" class="headerlink" title="let和const用哪个"></a><code>let</code>和<code>const</code>用哪个</h2><p>现在我们有两种作用域相似的声明方式,我们自然会问到底应该使用哪个。 与大多数泛泛的问题一样,答案是:依情况而定。</p><p>使用<a href="https://en.wikipedia.org/wiki/Principle_of_least_privilege">最小特权原则</a>,所有变量除了你计划去修改的都应该使用<code>const</code>。 基本原则就是如果一个变量不需要对它写入,那么其它使用这些代码的人也不能够写入它们,并且要思考为什么会需要对这些变量重新赋值。 使用<code>const</code>也可以让我们更容易的推测数据的流动。</p><p>另一方面,用户很喜欢<code>let</code>的简洁性。 这个手册大部分地方都使用了<code>let</code>。</p><h2 id="解构数组"><a href="#解构数组" class="headerlink" title="解构数组"></a>解构数组</h2><p>最简单的解构莫过于数组的解构赋值了:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> input = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>];<br><span class="hljs-keyword">let</span> [first, second] = input;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(first); <span class="hljs-comment">// outputs 1</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(second); <span class="hljs-comment">// outputs 2</span><br></code></pre></td></tr></table></figure><p>这创建了2个命名变量 <code>first</code> 和 <code>second</code>。 相当于使用了索引,但更为方便:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript">first = input[<span class="hljs-number">0</span>];<br>second = input[<span class="hljs-number">1</span>];<br></code></pre></td></tr></table></figure><p>解构作用于已声明的变量会更好:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// swap variables</span><br>[first, second] = [second, first];<br></code></pre></td></tr></table></figure><p>作用于函数参数:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">f</span>(<span class="hljs-params">[first, second]: [<span class="hljs-built_in">number</span>, <span class="hljs-built_in">number</span>]</span>) {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(first);<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(second);<br>}<br><span class="hljs-title function_">f</span>(input);<br></code></pre></td></tr></table></figure><p>你可以在数组里使用<code>...</code>语法创建剩余变量:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> [first, ...rest] = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>];<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(first); <span class="hljs-comment">// outputs 1</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(rest); <span class="hljs-comment">// outputs [ 2, 3, 4 ]</span><br></code></pre></td></tr></table></figure><p>当然,由于是JavaScript, 你可以忽略你不关心的尾随元素:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> [first] = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>];<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(first); <span class="hljs-comment">// outputs 1</span><br></code></pre></td></tr></table></figure><p>或其它元素:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> [, second, , fourth] = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>];<br></code></pre></td></tr></table></figure><h2 id="对象解构"><a href="#对象解构" class="headerlink" title="对象解构"></a>对象解构</h2><p>你也可以解构对象:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> o = {<br> <span class="hljs-attr">a</span>: <span class="hljs-string">"foo"</span>,<br> <span class="hljs-attr">b</span>: <span class="hljs-number">12</span>,<br> <span class="hljs-attr">c</span>: <span class="hljs-string">"bar"</span><br>};<br><span class="hljs-keyword">let</span> { a, b } = o;<br></code></pre></td></tr></table></figure><p>这通过 <code>o.a</code> and <code>o.b</code> 创建了 <code>a</code> 和 <code>b</code> 。 注意,如果你不需要 <code>c</code> 你可以忽略它。</p><p>就像数组解构,你可以用没有声明的赋值:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs typescript">({ a, b } = { <span class="hljs-attr">a</span>: <span class="hljs-string">"baz"</span>, <span class="hljs-attr">b</span>: <span class="hljs-number">101</span> });<br></code></pre></td></tr></table></figure><p>注意,我们需要用括号将它括起来,因为Javascript通常会将以 <code>{</code> 起始的语句解析为一个块。</p><p>你可以在对象里使用<code>...</code>语法创建剩余变量:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> { a, ...passthrough } = o;<br><span class="hljs-keyword">let</span> total = passthrough.<span class="hljs-property">b</span> + passthrough.<span class="hljs-property">c</span>.<span class="hljs-property">length</span>;<br></code></pre></td></tr></table></figure><h2 id="属性重命名"><a href="#属性重命名" class="headerlink" title="属性重命名"></a>属性重命名</h2><p>你也可以给属性以不同的名字:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> { <span class="hljs-attr">a</span>: newName1, <span class="hljs-attr">b</span>: newName2 } = o;<br></code></pre></td></tr></table></figure><p>这里的语法开始变得混乱。 你可以将 <code>a: newName1</code> 读做 “<code>a</code> 作为 <code>newName1</code>“。 方向是从左到右,好像你写成了以下样子:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> newName1 = o.<span class="hljs-property">a</span>;<br><span class="hljs-keyword">let</span> newName2 = o.<span class="hljs-property">b</span>;<br></code></pre></td></tr></table></figure><p>令人困惑的是,这里的冒号<em>不是</em>指示类型的。 如果你想指定它的类型, 仍然需要在其后写上完整的模式。</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> {a, b}: {<span class="hljs-attr">a</span>: <span class="hljs-built_in">string</span>, <span class="hljs-attr">b</span>: <span class="hljs-built_in">number</span>} = o;<br></code></pre></td></tr></table></figure><h2 id="默认值"><a href="#默认值" class="headerlink" title="默认值"></a>默认值</h2><p>默认值可以让你在属性为 undefined 时使用缺省值:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">keepWholeObject</span>(<span class="hljs-params">wholeObject: { a: <span class="hljs-built_in">string</span>, b?: <span class="hljs-built_in">number</span> }</span>) {<br> <span class="hljs-keyword">let</span> { a, b = <span class="hljs-number">1001</span> } = wholeObject;<br>}<br></code></pre></td></tr></table></figure><p>现在,即使 <code>b</code> 为 undefined , <code>keepWholeObject</code> 函数的变量 <code>wholeObject</code> 的属性 <code>a</code> 和 <code>b</code> 都会有值。</p><h2 id="函数声明"><a href="#函数声明" class="headerlink" title="函数声明"></a>函数声明</h2><p>解构也能用于函数声明。 看以下简单的情况:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">type</span> C = { <span class="hljs-attr">a</span>: <span class="hljs-built_in">string</span>, b?: <span class="hljs-built_in">number</span> }<br><span class="hljs-keyword">function</span> <span class="hljs-title function_">f</span>(<span class="hljs-params">{ a, b }: C</span>): <span class="hljs-built_in">void</span> {<br> <span class="hljs-comment">// ...</span><br>}<br></code></pre></td></tr></table></figure><p>但是,通常情况下更多的是指定默认值,解构默认值有些棘手。 首先,你需要在默认值之前设置其格式。</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">f</span>(<span class="hljs-params">{ a, b } = { a: <span class="hljs-string">""</span>, b: <span class="hljs-number">0</span> }</span>): <span class="hljs-built_in">void</span> {<br> <span class="hljs-comment">// ...</span><br>}<br><span class="hljs-title function_">f</span>(); <span class="hljs-comment">// ok, default to { a: "", b: 0 }</span><br></code></pre></td></tr></table></figure><p>其次,你需要知道在解构属性上给予一个默认或可选的属性用来替换主初始化列表。 要知道 <code>C</code> 的定义有一个 <code>b</code> 可选属性:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">f</span>(<span class="hljs-params">{ a, b = <span class="hljs-number">0</span> } = { a: <span class="hljs-string">""</span> }</span>): <span class="hljs-built_in">void</span> {<br> <span class="hljs-comment">// ...</span><br>}<br><span class="hljs-title function_">f</span>({ <span class="hljs-attr">a</span>: <span class="hljs-string">"yes"</span> }); <span class="hljs-comment">// ok, default b = 0</span><br><span class="hljs-title function_">f</span>(); <span class="hljs-comment">// ok, default to {a: ""}, which then defaults b = 0</span><br><span class="hljs-title function_">f</span>({}); <span class="hljs-comment">// error, 'a' is required if you supply an argument</span><br></code></pre></td></tr></table></figure><p><strong>要小心使用解构。 从前面的例子可以看出,就算是最简单的解构表达式也是难以理解的。 尤其当存在深层嵌套解构的时候,就算这时没有堆叠在一起的重命名,默认值和类型注解,也是令人难以理解的。 解构表达式要尽量保持小而简单。 你自己也可以直接使用解构将会生成的赋值表达式。</strong></p><h2 id="展开"><a href="#展开" class="headerlink" title="展开"></a>展开</h2><p>展开操作符正与解构相反。 它允许你将一个数组展开为另一个数组,或将一个对象展开为另一个对象。 例如:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> first = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>];<br><span class="hljs-keyword">let</span> second = [<span class="hljs-number">3</span>, <span class="hljs-number">4</span>];<br><span class="hljs-keyword">let</span> bothPlus = [<span class="hljs-number">0</span>, ...first, ...second, <span class="hljs-number">5</span>];<br></code></pre></td></tr></table></figure><p>这会令<code>bothPlus</code>的值为<code>[0, 1, 2, 3, 4, 5]</code>。 展开操作创建了<code>first</code>和<code>second</code>的一份浅拷贝。 它们不会被展开操作所改变。</p><p>你还可以展开对象:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> defaults = { <span class="hljs-attr">food</span>: <span class="hljs-string">"spicy"</span>, <span class="hljs-attr">price</span>: <span class="hljs-string">"$$"</span>, <span class="hljs-attr">ambiance</span>: <span class="hljs-string">"noisy"</span> };<br><span class="hljs-keyword">let</span> search = { ...defaults, <span class="hljs-attr">food</span>: <span class="hljs-string">"rich"</span> };<br></code></pre></td></tr></table></figure><p><code>search</code>的值为<code>{ food: "rich", price: "$$", ambiance: "noisy" }</code>。 对象的展开比数组的展开要复杂的多。 像数组展开一样,它是从左至右进行处理,但结果仍为对象。 这就意味着出现在展开对象后面的属性会覆盖前面的属性。 因此,如果我们修改上面的例子,在结尾处进行展开的话:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> defaults = { <span class="hljs-attr">food</span>: <span class="hljs-string">"spicy"</span>, <span class="hljs-attr">price</span>: <span class="hljs-string">"$$"</span>, <span class="hljs-attr">ambiance</span>: <span class="hljs-string">"noisy"</span> };<br><span class="hljs-keyword">let</span> search = { <span class="hljs-attr">food</span>: <span class="hljs-string">"rich"</span>, ...defaults };<br></code></pre></td></tr></table></figure><p>那么,<code>defaults</code>里的<code>food</code>属性会重写<code>food: "rich"</code>,在这里这并不是我们想要的结果。</p><p>对象展开还有其它一些意想不到的限制。 首先,它仅包含对象 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties">自身的可枚举属性</a>。 大体上是说当你展开一个对象实例时,你会丢失其方法:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">C</span> {<br> p = <span class="hljs-number">12</span>;<br> <span class="hljs-title function_">m</span>(<span class="hljs-params"></span>) {<br> }<br>}<br><span class="hljs-keyword">let</span> c = <span class="hljs-keyword">new</span> <span class="hljs-title function_">C</span>();<br><span class="hljs-keyword">let</span> clone = { ...c };<br>clone.<span class="hljs-property">p</span>; <span class="hljs-comment">// ok</span><br>clone.<span class="hljs-title function_">m</span>(); <span class="hljs-comment">// error!</span><br></code></pre></td></tr></table></figure>]]></content>
<summary type="html">Javascript进阶版👽</summary>
<category term="技术栈" scheme="http://example.com/categories/%E6%8A%80%E6%9C%AF%E6%A0%88/"/>
<category term="前端" scheme="http://example.com/tags/%E5%89%8D%E7%AB%AF/"/>
<category term="笔记" scheme="http://example.com/tags/%E7%AC%94%E8%AE%B0/"/>
</entry>
<entry>
<title>Interview&Knowledge about Web-Front</title>
<link href="http://example.com/2023/12/06/Interview-Knowledge-about-Web-Front/"/>
<id>http://example.com/2023/12/06/Interview-Knowledge-about-Web-Front/</id>
<published>2023-12-06T04:28:54.000Z</published>
<updated>2024-03-16T11:47:15.039Z</updated>
<content type="html"><![CDATA[<h3 id="前端未来的展望✨"><a href="#前端未来的展望✨" class="headerlink" title="前端未来的展望✨"></a>前端未来的展望✨</h3><p>当前PC和Mobile端前端都开发得差不多了,渐渐趋于一个稳态的状态,我们不妨展望一下未来:</p><ul><li>ChatGPT在短期内很快就兴起了,最为容易看到的就是我去年这个时间节点还在自己手搓代码,但是这一届的学弟学妹已经开始使用GPT进行查找代码错误和提供代码思路了🤕。所以GPTwith前端、也可以推广到AIwith前端是一个大方向,但是前端这个东西似乎不是很适合机器学习,目前能做的好像我知道的就是用于代码优化(指机器学习作用于前端)。</li><li>脑机接口近年来也开始兴起,前端作为人机交互工程师,未来脑机接口热潮的时候一定是一个风口浪尖。</li><li>语音转文字前端也是一个点。</li></ul><h3 id="前端人应该拥有的素养❤️"><a href="#前端人应该拥有的素养❤️" class="headerlink" title="前端人应该拥有的素养❤️"></a>前端人应该拥有的素养❤️</h3><ul><li>Blog要经常记录,我打算寒假就让学弟学妹们去制作一个自己的blog,可以使用vercel、4everland自己部署,也可以hexo+github部署……自己决定。Blog内容还是尽量自己手敲(这点我自己也没有做到,自己手敲上去的东西更加属于自己,虽然复制粘贴文档的显得工作量更多🥺)</li><li>积极思考,常常思考自己的代码有没有改进的地方,这个是从韦华贤学长那里学到的,事件点是在我的tasklist有一个函数一眼就需要封装一下,自己很蠢的没看出来,和他沟通之后他说是一个习惯问题,我仔细思考过后觉得这个也是一个前端人应该拥有的素养😈</li><li>拥有好奇心和自趣力——前端-WEB-或者说整个计算机行业都是快速迭代的,需要你跳出工作&其他需求式编程去自己学习自己钻研,这个过程是相当有趣的。</li><li>责任心这个东西就算跳开前端工程师这个tag也是很重要的东西,它是可以伴随你一生的良好品质,不管是平日的生活遇到的东西还是以后自己项目中会遇到的一些事情,你都需要一个很重的责任心去维护一些东西。</li><li>增加学习深度,扩宽学习广度:这个是一个很有意思的问题,在我多方向调研和请教很多人过后,我得到一个结论:在国内大环境,广度重要性远大于深度重要性(至少对于前端且考虑范围取最大)。这过程中我请教了厚华学长、阿韦学长、环节、工具箱学长,各有说辞:<ul><li>厚华学长在准备实习,有很多自己整理出来的面经,他得到的结论是,我需要去弄懂很多之前已经学过会用的,但是基层逻辑不懂的东西,确实是这样,他share过来的很多面试题目我基本看了只能答出表层的东西,再问深一点就没办法说出它的底层逻辑了,但是我认为这个是一个很基本的深度(本来就需要去掌握的东西)以至于他不能算是深度。</li><li>第二个就是阿韦,在深度广度这一块的话给的建议是先学透一个,这样基本原理弄清楚之后其他也会好搞很多。</li><li>工具箱学长也是说建议有自己能拿出手的东西,深度。</li><li>但是面向实际开发中,不管是大厂小厂,都需要你有一个很广的技术栈,会了web需要app,甚至后端、操作系统、ui都需要。</li></ul></li></ul><h3 id="漫谈🎇"><a href="#漫谈🎇" class="headerlink" title="漫谈🎇"></a>漫谈🎇</h3><ul><li>面试相关问题:<ul><li>对于前端工程师面试中更加需要注意的是编程范式的问题,作为一个刚刚毕业或者还没有毕业的小东西,当你没有一个非常专业or深度的知识的话,面试官更加有可能考你的是很基础的编程——数据结构等。</li><li>对于后端工程师,需要通透的是数据库有关知识,这里我不是很了解,不多胡诌了。</li><li>如果拥有自己的项目的话,面试官会问项目相关架构。</li><li>更加重要的是,你需要面试的时候自己编写代码,这就需要你拥有相关的能力。</li></ul></li><li>面试八股文这一块,我有一个观点,我觉得这个属于一个戏称,其实面试中提到的问题我个人认为还是很有用的,通透原理才能使用。所以我觉得多收集多解决这些问题还是很有趣的,有时候还能遇到一些自己不会的问题。</li><li>当你通过面试进入公司之后技术就不会是最难的东西了,更加难的是团队的协作等。这是一个很有趣的我从一些前端大牛身上拿到的观点。</li><li>多投简历、脸皮要厚,什么想投的都去尝试,过后成或不成都可以促进你的学习——在面试中没有解决的问题可以自己花时间去解决。</li><li>多参与开源项目,可能一开始在开源项目中能做的很少,但是这是一个渐进的过程,后面就可以做的多起来了。</li></ul>]]></content>
<summary type="html">写一些目前的想法。</summary>
<category term="随笔" scheme="http://example.com/categories/%E9%9A%8F%E7%AC%94/"/>
<category term="😶🌫️" scheme="http://example.com/tags/%F0%9F%98%B6%E2%80%8D%F0%9F%8C%AB%EF%B8%8F/"/>
</entry>
<entry>
<title>MITT</title>
<link href="http://example.com/2023/11/13/MITT/"/>
<id>http://example.com/2023/11/13/MITT/</id>
<published>2023-11-13T06:58:08.000Z</published>
<updated>2024-03-20T08:49:31.843Z</updated>
<content type="html"><![CDATA[<p>在Vue3中为了优化代码会使用全局事件总线bus去在不同组件之间传值。</p><p>首先先安装一下mitt</p><figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmake">npm <span class="hljs-keyword">install</span> mitt<br></code></pre></td></tr></table></figure><p>添加一个bus.js的文件里面放这些</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> mitt <span class="hljs-keyword">from</span> <span class="hljs-string">'mitt'</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> events = <span class="hljs-title function_">mitt</span>()<br></code></pre></td></tr></table></figure><p>在需要使用bus的组件里引入依赖</p><figure class="highlight clean"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs clean"><span class="hljs-keyword">import</span> { events } <span class="hljs-keyword">from</span> <span class="hljs-string">'.../.../bus.js'</span><br></code></pre></td></tr></table></figure><p>使用方法主要是三种:</p><ul><li><p>emit:想要传出值或函数</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript">events.<span class="hljs-title function_">emit</span>(<span class="hljs-string">'functionName'</span>, postValue)<br><span class="hljs-comment">//其中functionName是你绑定的一个函数名,相当于一个标识,可以在不同组件中靠这个来判定来源和目的地,postValue是你要传的值。</span><br></code></pre></td></tr></table></figure></li><li><p>on:想要接受传入值</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript">events.<span class="hljs-title function_">on</span>(<span class="hljs-string">'functionName'</span>, <span class="hljs-function">(<span class="hljs-params">val</span>) =></span> { ... })<br><span class="hljs-comment">//其中functionName是你绑定的一个函数名,相当于一个标识,可以在不同组件中靠这个来判定来源和目的地,val是你上面传出来的postValue,要干什么自己写在...里。</span><br></code></pre></td></tr></table></figure><p>兄弟组件之间使用on会有一个小问题,详见<a href="https://taskmanagerol.github.io/2024/01/30/Problem/">Problem</a> </p></li><li><p>off:想要解绑事件</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//某些情况可能要解绑</span><br>events.<span class="hljs-title function_">off</span>(<span class="hljs-string">"functionName"</span>)<br></code></pre></td></tr></table></figure></li></ul>]]></content>
<summary type="html">一个全局传参的JavaScript库</summary>
<category term="技术栈" scheme="http://example.com/categories/%E6%8A%80%E6%9C%AF%E6%A0%88/"/>
<category term="前端" scheme="http://example.com/tags/%E5%89%8D%E7%AB%AF/"/>
<category term="笔记" scheme="http://example.com/tags/%E7%AC%94%E8%AE%B0/"/>
</entry>
<entry>
<title>Vue.Config</title>
<link href="http://example.com/2023/11/13/Vue.Config/"/>
<id>http://example.com/2023/11/13/Vue.Config/</id>
<published>2023-11-13T06:57:44.000Z</published>
<updated>2024-04-24T11:22:43.826Z</updated>
<content type="html"><![CDATA[<h2 id="Vite框架项目创建"><a href="#Vite框架项目创建" class="headerlink" title="Vite框架项目创建"></a>Vite框架项目创建</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs bash">npm create vite@latest<br>npm install<br>npm run dev<br>//(别忘记在package.json中<span class="hljs-string">"scripts"</span>对象中<span class="hljs-string">"dev"</span>后面把<span class="hljs-string">"vite"</span>改成<span class="hljs-string">"vite --open"</span>)<br></code></pre></td></tr></table></figure><h2 id="Vue-Router路由安装"><a href="#Vue-Router路由安装" class="headerlink" title="Vue Router路由安装"></a>Vue Router路由安装</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">npm install vue-router@4<br>//安装后别忘记在src下新建一个router子文件夹和index.js、routes.js子文件<br></code></pre></td></tr></table></figure><h3 id="index-js(直接复制粘贴即可)"><a href="#index-js(直接复制粘贴即可)" class="headerlink" title="index.js(直接复制粘贴即可)"></a>index.js(直接复制粘贴即可)</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">// 导入router所需的方法</span><br><span class="hljs-keyword">import</span> { createRouter, createWebHashHistory } <span class="hljs-keyword">from</span> <span class="hljs-string">'vue-router'</span><br><br><span class="hljs-comment">// 导入路由页面的配置</span><br><span class="hljs-keyword">import</span> routes <span class="hljs-keyword">from</span> <span class="hljs-string">'./routes.js'</span><br><br><span class="hljs-comment">// 路由参数配置</span><br><span class="hljs-keyword">const</span> router = <span class="hljs-title function_">createRouter</span>({<br> <span class="hljs-comment">// 使用hash(createWebHashHistory)模式,(createWebHistory是HTML5历史模式,支持SEO)</span><br> <span class="hljs-attr">history</span>: <span class="hljs-title function_">createWebHashHistory</span>(),<br> <span class="hljs-attr">routes</span>: routes,<br>})<br><br><span class="hljs-comment">// 全局前置守卫,这里可以加入用户登录判断</span><br>router.<span class="hljs-title function_">beforeEach</span>(<span class="hljs-function">(<span class="hljs-params">to, <span class="hljs-keyword">from</span>, next</span>) =></span> {<br> <span class="hljs-comment">// 继续前进 next()</span><br> <span class="hljs-comment">// 返回 false 以取消导航</span><br> <span class="hljs-title function_">next</span>()<br>})<br><br><span class="hljs-comment">// 全局后置钩子,这里可以加入改变页面标题等操作</span><br>router.<span class="hljs-title function_">afterEach</span>(<span class="hljs-function">(<span class="hljs-params">to, <span class="hljs-keyword">from</span></span>) =></span> {<br> <span class="hljs-comment">// const _title = to.meta.title</span><br> <span class="hljs-comment">// if (_title) {</span><br> <span class="hljs-comment">// window.document.title = _title</span><br> <span class="hljs-comment">// }</span><br>})<br><br><span class="hljs-comment">// 导出默认值</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> router<br></code></pre></td></tr></table></figure><h3 id="routes-js(直接复制粘贴即可)"><a href="#routes-js(直接复制粘贴即可)" class="headerlink" title="routes.js(直接复制粘贴即可)"></a>routes.js(直接复制粘贴即可)</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">const</span> routes = [<br> {<br> <span class="hljs-attr">path</span>: <span class="hljs-string">'/'</span>,<br> <span class="hljs-attr">name</span>: <span class="hljs-string">'HOME'</span>,<br> <span class="hljs-attr">component</span>: <span class="hljs-function">() =></span> <span class="hljs-keyword">import</span>(<span class="hljs-string">''</span>)<br> }<br>]<br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> routes<br></code></pre></td></tr></table></figure><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//最后就是别忘记在main.js里添加引入依赖</span><br><span class="hljs-keyword">import</span> router <span class="hljs-keyword">from</span> <span class="hljs-string">'./router/index.js'</span><br><span class="hljs-title function_">createApp</span>(<span class="hljs-title class_">App</span>).<span class="hljs-title function_">use</span>(router).<span class="hljs-title function_">mount</span>(<span class="hljs-string">'#app'</span>)<span class="hljs-comment">//.use(router)</span><br></code></pre></td></tr></table></figure><h2 id="APP-vue初始化"><a href="#APP-vue初始化" class="headerlink" title="APP.vue初始化"></a>APP.vue初始化</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs vue"><script setup></script><br><br><template><br> <router-view></router-view><br></template><br><br><style scoped></style><br></code></pre></td></tr></table></figure><h2 id="style-css初始化"><a href="#style-css初始化" class="headerlink" title="style.css初始化"></a>style.css初始化</h2><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-comment">/* 部分标签修改 */</span><br><span class="hljs-selector-tag">body</span> {<br> <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;<br> <span class="hljs-attribute">display</span>: flex;<br> place-items: center;<br>}<br><br><span class="hljs-selector-id">#app</span> {<br> <span class="hljs-attribute">max-width</span>: <span class="hljs-number">1280px</span>;<br> <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> auto;<br> <span class="hljs-attribute">text-align</span>: center;<br>}<br></code></pre></td></tr></table></figure>]]></content>
<summary type="html">每次新建项目都得配置不少东西,在这里标记一下防止遗忘。</summary>
<category term="技术栈" scheme="http://example.com/categories/%E6%8A%80%E6%9C%AF%E6%A0%88/"/>
<category term="前端" scheme="http://example.com/tags/%E5%89%8D%E7%AB%AF/"/>
<category term="😶🌫️" scheme="http://example.com/tags/%F0%9F%98%B6%E2%80%8D%F0%9F%8C%AB%EF%B8%8F/"/>
</entry>
<entry>
<title>Canvas</title>
<link href="http://example.com/2023/07/21/Canvas/"/>
<id>http://example.com/2023/07/21/Canvas/</id>
<published>2023-07-21T07:53:10.000Z</published>
<updated>2024-03-25T08:37:38.118Z</updated>
<content type="html"><![CDATA[<h1 id="canvas画布使用——CSS进阶"><a href="#canvas画布使用——CSS进阶" class="headerlink" title="canvas画布使用——CSS进阶"></a>canvas画布使用——CSS进阶</h1><p>在大一的时候学的一些高数、线性代数都可以用于canvas画布,所以还是很重要的,能好好学就好好学。</p><p>文章参考:<a href="https://www.jianshu.com/p/e3ebe08dddad">在canvas上绘制3d图形 - 简书 (jianshu.com)</a>(写得真的很好,少见的好文章)</p><h3 id="简单绘制三维图形"><a href="#简单绘制三维图形" class="headerlink" title="简单绘制三维图形"></a>简单绘制三维图形</h3><p>因为canvas是一个二维的东西,所以我们想要画出三维的图形就要考虑把这个三维图形给投影到二维上,进而给造成一种三维的错觉。所以首先需要学习的是如何表示三维坐标轴上的任意一个点。通过文章中的推导我们可以看到:</p><p>从空间内的任意点A(xA,yA,zA)观察空间内的任一点G(xG,yG,zG),它在xy平面内的投影H的坐标为:</p><p> $x = ((xG-xA)*zA)/(zA-zG) ; y = ((yG-yA)*zA)/(zA-zG)$</p><h3 id="三维图形-的旋转"><a href="#三维图形-的旋转" class="headerlink" title="三维图形 的旋转"></a>三维图形 的旋转</h3><p>对于一个图形,如果要对其进行y轴的旋转(从观察点更为明显且符合逻辑),则从y轴向下俯视xz平面可以使用一个极坐标的逻辑从而确定我们变换之后的坐标点。<br>主要就是确定每个点(控制旋转的是角度)</p><p><img src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8xMDk2NTEyMi1kMmM1NWUzNTFhMmQ0Zjc1LnBuZz9pbWFnZU1vZ3IyL2F1dG8tb3JpZW50L3N0cmlwfGltYWdlVmlldzIvMi93LzMxMS9mb3JtYXQvd2VicA?x-oss-process=image/format,png" alt="img"></p><p>这个时候假定D点与x轴的夹角是α,圆的半径为R,将D点绕着y轴旋转β旋转至D’点,这个时候D’与x轴夹角为α+β,此时D’的x坐标为cos(α+β)*R,D’的z坐标为sin(α+β)*R</p><p>D’的x坐标:</p><p>$cos(α+β)<em>R=R</em>cosα<em>cosβ-R</em>sinα*sinβ$</p><p>D’的z坐标sin(α+β)<em>R=R</em>sinα<em>cosβ+R</em>cosα<em>sinβ<br>而R</em>sinα就是旋转之前D点的z坐标,R<em>cosα就是旋转之前D点的x坐标,<br>D’的x坐标为x</em>cosβ-z<em>sinβ<br>D’的z坐标为z</em>cosβ+x<em>sinβ<br>将结论代入到我们的立方体的8个顶点ABCDEFGH中<br>对于任一点D(xD,yD,zD),其绕y轴旋转β角的时候,它的三维坐标变为(xD</em>cosβ-zD<em>sinβ,yD,zD</em>cosβ+xD*sinβ)</p><h3 id="正弦曲线阵(含代码)"><a href="#正弦曲线阵(含代码)" class="headerlink" title="正弦曲线阵(含代码)"></a>正弦曲线阵(含代码)</h3><p>博客中写的是vue2的,我自己用的是vue3,所以以下是我已经写好的正弦曲线阵代码。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">canvas</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"wave"</span> <span class="hljs-attr">:width</span>=<span class="hljs-string">"canvasWidth"</span> <span class="hljs-attr">:height</span>=<span class="hljs-string">"canvasHeight"</span>></span><span class="hljs-tag"></<span class="hljs-name">canvas</span>></span><br></code></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//绘制正弦波浪canvas</span><br><span class="hljs-keyword">import</span> { ref, watch } <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span>; <br><span class="hljs-keyword">const</span> wave = <span class="hljs-title function_">ref</span>(<span class="hljs-string">''</span>)<br><span class="hljs-keyword">const</span> canvasWidth = <span class="hljs-title function_">ref</span>(<span class="hljs-number">1920</span>)<br><span class="hljs-keyword">const</span> canvasHeight = <span class="hljs-title function_">ref</span>(<span class="hljs-number">800</span>)<br><span class="hljs-comment">//构建一个结构体 方便后期绘制多条正弦曲线</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Line</span> {<br> <span class="hljs-title function_">constructor</span> (a, b, c, d, z, start, end, gap) {<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">a</span> = a<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">b</span> = b<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">c</span> = c<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">d</span> = d <span class="hljs-comment">//以上四个控制正弦函数振幅周期之类的</span><br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">z</span> = z <span class="hljs-comment">//三维坐标</span><br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">start</span> = start <span class="hljs-comment">//绘画开始点</span><br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">end</span> = end <span class="hljs-comment">//绘画结束点</span><br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">gap</span> = gap <span class="hljs-comment">//间距</span><br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">pointList</span> = []<br> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">computePointList</span>()<br> }<br> computePointList () {<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">pointList</span> = []<br> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-variable language_">this</span>.<span class="hljs-property">start</span>; i <= <span class="hljs-variable language_">this</span>.<span class="hljs-property">end</span>; i = i + <span class="hljs-variable language_">this</span>.<span class="hljs-property">gap</span>) {<br> <span class="hljs-keyword">let</span> x = i<br> <span class="hljs-keyword">let</span> y = <span class="hljs-variable language_">this</span>.<span class="hljs-property">a</span> * <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">sin</span>((<span class="hljs-variable language_">this</span>.<span class="hljs-property">b</span> * x + <span class="hljs-variable language_">this</span>.<span class="hljs-property">c</span>) / <span class="hljs-number">180</span> * <span class="hljs-title class_">Math</span>.<span class="hljs-property">PI</span>) + <span class="hljs-variable language_">this</span>.<span class="hljs-property">d</span> <span class="hljs-comment">// 即y = A sin(ωx + φ) + B</span><br> <span class="hljs-keyword">let</span> offset = i <span class="hljs-comment">//偏移量用来让他运动</span><br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">pointList</span>.<span class="hljs-title function_">push</span>({<br> x,<br> y,<br> <span class="hljs-attr">z</span>: <span class="hljs-variable language_">this</span>.<span class="hljs-property">z</span>,<br> <span class="hljs-attr">originX</span>: x,<br> offset<br> })<br> }<br> }<br>}<br><span class="hljs-keyword">const</span> lineList = [<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">390</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">360</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">330</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">300</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">270</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">240</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">210</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">180</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">150</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">120</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">90</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">60</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">30</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">30</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">60</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">90</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">120</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">150</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">180</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">210</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">240</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">270</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">300</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <br>]<span class="hljs-comment">//整个类的列表出来</span><br><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">draw</span> = (<span class="hljs-params">visual</span>) => { <span class="hljs-comment">//这是个绘制正弦点的函数</span><br> <span class="hljs-keyword">const</span> context = wave.<span class="hljs-property">value</span>.<span class="hljs-title function_">getContext</span>(<span class="hljs-string">"2d"</span>);<br> context.<span class="hljs-title function_">clearRect</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, canvasWidth.<span class="hljs-property">value</span>, canvasHeight.<span class="hljs-property">value</span>) <span class="hljs-comment">//清空像素</span><br> lineList.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">line</span> =></span> {<br> line.<span class="hljs-property">pointList</span>.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">item</span> =></span> {<br> <span class="hljs-keyword">const</span> pointSize = <span class="hljs-number">1.5</span> * visual.<span class="hljs-property">z</span> / (visual.<span class="hljs-property">z</span> - item.<span class="hljs-property">z</span>) <span class="hljs-comment">//整个近大远小</span><br> context.<span class="hljs-title function_">beginPath</span>()<br> context.<span class="hljs-title function_">arc</span>(item.<span class="hljs-property">canvasX</span> + canvasWidth.<span class="hljs-property">value</span> / <span class="hljs-number">2</span>, item.<span class="hljs-property">canvasY</span> + canvasHeight.<span class="hljs-property">value</span> / <span class="hljs-number">2</span>, pointSize, <span class="hljs-number">0</span>, <span class="hljs-number">2</span> * <span class="hljs-title class_">Math</span>.<span class="hljs-property">PI</span>) <span class="hljs-comment">//arc(x, y, radius, startAngle, endAngle, counterclockwise);</span><br> context.<span class="hljs-title function_">closePath</span>()<br> context.<span class="hljs-title function_">fill</span>()<br> })<br> })<br>}<br><span class="hljs-keyword">const</span> <span class="hljs-title function_">updatePointList</span> = (<span class="hljs-params">rotationAngleSpeed, visual</span>) => { <span class="hljs-comment">//这是个更新点的位置而使正弦函数移动的函数</span><br> lineList.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">line</span> =></span> {<br> line.<span class="hljs-property">pointList</span>.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">item</span> =></span> {<br> <span class="hljs-keyword">let</span> x = item.<span class="hljs-property">x</span><br> <span class="hljs-keyword">let</span> z = item.<span class="hljs-property">z</span><br> item.<span class="hljs-property">x</span> = x * <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">cos</span>(rotationAngleSpeed / <span class="hljs-number">180</span> * <span class="hljs-title class_">Math</span>.<span class="hljs-property">PI</span>) - z * <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">sin</span>(rotationAngleSpeed / <span class="hljs-number">180</span> * <span class="hljs-title class_">Math</span>.<span class="hljs-property">PI</span>) <br> item.<span class="hljs-property">z</span> = z * <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">cos</span>(rotationAngleSpeed / <span class="hljs-number">180</span> * <span class="hljs-title class_">Math</span>.<span class="hljs-property">PI</span>) + x * <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">sin</span>(rotationAngleSpeed / <span class="hljs-number">180</span> * <span class="hljs-title class_">Math</span>.<span class="hljs-property">PI</span>) <br> item.<span class="hljs-property">y</span> = line.<span class="hljs-property">a</span> * <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">sin</span>((line.<span class="hljs-property">b</span> * item.<span class="hljs-property">originX</span> + line.<span class="hljs-property">c</span> + item.<span class="hljs-property">offset</span>) / <span class="hljs-number">180</span> * <span class="hljs-title class_">Math</span>.<span class="hljs-property">PI</span>) + line.<span class="hljs-property">d</span> <span class="hljs-comment">//绕y轴旋转所以y比较特别</span><br> item.<span class="hljs-property">canvasX</span> = (item.<span class="hljs-property">x</span> - visual.<span class="hljs-property">x</span>) * visual.<span class="hljs-property">z</span> / (visual.<span class="hljs-property">z</span> - z)<br> item.<span class="hljs-property">canvasY</span> = (item.<span class="hljs-property">y</span> - visual.<span class="hljs-property">y</span>) * visual.<span class="hljs-property">z</span> / (visual.<span class="hljs-property">z</span> - z)<br> })<br> })<br>}<br><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">animationFrame</span> = (<span class="hljs-params">visual</span>) => { <span class="hljs-comment">//正弦函数动画</span><br> <span class="hljs-variable language_">window</span>.<span class="hljs-title function_">requestAnimationFrame</span>(<span class="hljs-function">() =></span> {<br> lineList.<span class="hljs-title function_">forEach</span>(<span class="hljs-function">(<span class="hljs-params">line,index</span>) =></span> {<br> line.<span class="hljs-property">pointList</span>.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">item</span> =></span> {<br> line.<span class="hljs-property">c</span> = item.<span class="hljs-property">offset</span> + index * <span class="hljs-number">30</span> <span class="hljs-comment">//index控制偏移量更美观</span><br> item.<span class="hljs-property">offset</span> = item.<span class="hljs-property">offset</span> + <span class="hljs-number">1</span><br> })<br> <span class="hljs-title function_">updatePointList</span>(<span class="hljs-number">.003</span>,visual)<br> })<br> <span class="hljs-title function_">draw</span>(visual)<br> <span class="hljs-title function_">animationFrame</span>(visual)<br> })<br>}<br><span class="hljs-comment">//监听canvas标签创建、因为JS比标签创建更快,所以需要监听。</span><br><span class="hljs-title function_">watch</span>(wave, <span class="hljs-function">(<span class="hljs-params">newValue, oldValue</span>) =></span> {<br> <span class="hljs-keyword">const</span> visual = { <span class="hljs-comment">//观察点设置</span><br> <span class="hljs-attr">x</span>: <span class="hljs-number">0</span>,<br> <span class="hljs-attr">y</span>: -<span class="hljs-number">70</span>,<br> <span class="hljs-attr">z</span>: <span class="hljs-number">500</span><br> }<br> <span class="hljs-title function_">draw</span>(visual);<br> <span class="hljs-title function_">animationFrame</span>(visual)<br>})<br><br></code></pre></td></tr></table></figure>]]></content>
<summary type="html">Canvas画布学习,很多特殊效果都是用这个实现的。</summary>
<category term="技术栈" scheme="http://example.com/categories/%E6%8A%80%E6%9C%AF%E6%A0%88/"/>
<category term="前端" scheme="http://example.com/tags/%E5%89%8D%E7%AB%AF/"/>
<category term="笔记" scheme="http://example.com/tags/%E7%AC%94%E8%AE%B0/"/>
</entry>
<entry>
<title>TailwindCSS</title>
<link href="http://example.com/2023/06/29/TailwindCSS/"/>
<id>http://example.com/2023/06/29/TailwindCSS/</id>
<published>2023-06-29T02:31:19.000Z</published>
<updated>2024-04-24T08:59:17.995Z</updated>
<content type="html"><![CDATA[<h1 id="Tailwindcss介绍"><a href="#Tailwindcss介绍" class="headerlink" title="Tailwindcss介绍"></a>Tailwindcss介绍</h1><p>Tailwindcss是一种简单好用的css框架,我们在项目中经常遇见只需要赋一次样式的div。</p><p>要么在div上写class后再到css部分去修改样式,这样会相当麻烦(前端人想要6块屏幕呜呜呜),需要上下滑动或者分屏什么什么的。</p><p>要么就在div中使用style去进行修改,但是这样会有两个问题:一个是div中的style不可以配合vscode的插件进行一个自动补全,需要自己去记。另一个是很长很繁杂。</p><p>Tailwindcss就可以解决这样的问题,灵活、没有运行时的负担。</p><p>配置很简单,配置和学习使用半小时可以完成。</p><h1 id="Tailwindcss快速入门"><a href="#Tailwindcss快速入门" class="headerlink" title="Tailwindcss快速入门"></a>Tailwindcss快速入门</h1><p><a href="https://www.tailwindcss.cn/docs/installation/framework-guides">Framework Guides - TailwindCSS中文文档 | TailwindCSS中文网</a></p><p>此处点击选择进入相应的前端框架(我使用的Vite,然后呢进去有vue和react,一开始我没看见用的react配置,然后就没成。)</p><p>然后文档写得很详细了,缺点是他的中文文档似乎没有完全中文化,需要自己进行一个翻译。</p><p>大概使用就是</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-3xl font-bold underline"</span>></span>Home<span class="hljs-tag"></<span class="hljs-name">h1</span>></span><br></code></pre></td></tr></table></figure><h2 id="Vite快速配置"><a href="#Vite快速配置" class="headerlink" title="Vite快速配置"></a>Vite快速配置</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs bash">//在工作区安装tailwindcss<br>npm install -D tailwindcss postcss autoprefixer<br>npx tailwindcss init -p<br></code></pre></td></tr></table></figure><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//新创建的tailwind.config.js下复制如下代码</span><br><span class="hljs-comment">/** <span class="hljs-doctag">@type</span> {<span class="hljs-type">import('tailwindcss').Config</span>} */</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {<br> <span class="hljs-attr">content</span>: [<br> <span class="hljs-string">"./index.html"</span>,<br> <span class="hljs-string">"./src/**/*.{vue,js,ts,jsx,tsx}"</span>,<br> ],<br> <span class="hljs-attr">theme</span>: {<br> <span class="hljs-attr">extend</span>: {},<br> },<br> <span class="hljs-attr">plugins</span>: [],<br>}<br></code></pre></td></tr></table></figure><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs css">//在style<span class="hljs-selector-class">.css</span>中加入<br><span class="hljs-keyword">@tailwind</span> base;<br><span class="hljs-keyword">@tailwind</span> components;<br><span class="hljs-keyword">@tailwind</span> utilities;<br></code></pre></td></tr></table></figure>]]></content>
<summary type="html">CSS框架,减少很多代码量,但是不便于维护。</summary>
<category term="工具使用" scheme="http://example.com/categories/%E5%B7%A5%E5%85%B7%E4%BD%BF%E7%94%A8/"/>
<category term="工具" scheme="http://example.com/tags/%E5%B7%A5%E5%85%B7/"/>
<category term="前端" scheme="http://example.com/tags/%E5%89%8D%E7%AB%AF/"/>
<category term="速通" scheme="http://example.com/tags/%E9%80%9F%E9%80%9A/"/>
</entry>
<entry>
<title>Vue</title>
<link href="http://example.com/2023/06/24/Vue/"/>
<id>http://example.com/2023/06/24/Vue/</id>
<published>2023-06-24T10:02:16.000Z</published>
<updated>2024-06-24T04:16:36.353Z</updated>
<content type="html"><![CDATA[<h1 id="Webpack"><a href="#Webpack" class="headerlink" title="Webpack"></a>Webpack</h1><h3 id="前端工程化"><a href="#前端工程化" class="headerlink" title="前端工程化"></a>前端工程化</h3><p>(本来记录这个没什么意义,但是很符合我,就记下来了)</p><p>实际的前端开发:</p><ul><li>模块化(js的模块化,css模块化,资源的模块化)</li><li>组件化(复用现有的UI结构、样式、行为)</li><li>规范化(目录结构的划分、编码规范化、接口规范化、文档规范化、Git分支管理)</li><li>自动化(自动化构建、自动部署、自动化测试)</li></ul><p>而不是一开始所以为的缺什么组件或API直接去拿</p><h1 id="Vue"><a href="#Vue" class="headerlink" title="Vue"></a>Vue</h1><h3 id="vue简介"><a href="#vue简介" class="headerlink" title="vue简介"></a>vue简介</h3><p>Vue是一套用于构建用户界面的前端框架。</p><p>Vue框架的特性,主要体现在如下两个方面:</p><h5 id="数据驱动视图"><a href="#数据驱动视图" class="headerlink" title="数据驱动视图"></a>数据驱动视图</h5><p>在使用了vue的界面中,vue会监听数据的变化,从而自动重新渲染页面的结构。即当页面数据发生变化时,页面会自动重新渲染。</p><h5 id="双向数据绑定"><a href="#双向数据绑定" class="headerlink" title="双向数据绑定"></a>双向数据绑定</h5><p>在填写表单时,双向数据绑定可以辅助开发者在不操作DOM的前提下,自动把用户填写的内容同步到数据源中。开发者不需要再手动操作来获取表单元素的最新值。</p><h3 id="Vue的基本使用"><a href="#Vue的基本使用" class="headerlink" title="Vue的基本使用"></a>Vue的基本使用</h3><ul><li>导入Vue.js的script脚本文件</li><li>在页面中声明一个将要被Vue控制的DOM区域</li><li>创建vm实例对象</li></ul><h3 id="Vue的指令和过滤器"><a href="#Vue的指令和过滤器" class="headerlink" title="Vue的指令和过滤器"></a>Vue的指令和过滤器</h3><p>==过滤器只能在Vue2.x使用==</p><h5 id="指令"><a href="#指令" class="headerlink" title="指令"></a>指令</h5><p>指令时Vue为开发者提供的模板语法,用于辅助者渲染界面的基本结构</p><p>Vue中的指令按照不同的用途可以分为如下6大类:</p><ul><li><p>内容渲染指令</p><ul><li>v-text 覆盖原有的指令</li><li>双括号 插值</li><li>v-html 渲染含有标签的文本</li></ul></li><li><p>属性绑定指令</p><ul><li>如果需要为元素的属性动态绑定属性值,则需要用到v-bind属性绑定指令。可以简写成冒号:</li></ul></li><li><p>事件绑定指令</p><ul><li>v-on用于绑定事件,简写@,事件修饰符可以快速完成methods中定义的某些函数</li><li>常见的事件修饰符有:.stop阻止冒泡,.prevent阻止默认事件,.capture添加事件侦听器时使用事件捕获模式,.self只当事件在该元素本身触发时回调,.once事件只触发一次</li></ul></li><li><p>双向绑定指令</p><ul><li>v-model</li></ul></li><li><p>条件渲染指令</p><ul><li>v-if/v-show</li></ul></li><li><p>列表渲染指令</p></li></ul><h5 id="过滤器"><a href="#过滤器" class="headerlink" title="过滤器"></a>过滤器</h5><p>过滤器是vue为开发者提供的功能,常用于文本的格式化。过滤器可以用在两个地方:插值表达式 和 v-bind 属性绑定</p><p>和 el data methods 同级,filters 为过滤器,本质上还是一个函数,过滤器中,必须要有一个返回值</p><p>芝士私有过滤器</p><p>全局过滤器可以让任何一个vue实例使用</p><p>怎么定义呢?</p><p>Vue.filter(‘过滤器名称’,(str)=>{<br>balabalabala<br>})</p><h3 id="侦听器"><a href="#侦听器" class="headerlink" title="侦听器"></a>侦听器</h3><p>和 el data methods 同级,watch 为侦听器 可以随时观察数据变化 定义时用data中的数据定义 表示的是“如果改变就”</p><p>如果是data中的对象的对象 那定义时就是 单引号 对象.对象 单引号 这样</p><h3 id="计算属性"><a href="#计算属性" class="headerlink" title="计算属性"></a>计算属性</h3><p>计算属性指的时通过一系列运算之后,最终得到一个属性值。</p><p>这个动态计算出来的属性值可以被模板结构或methods方法使用</p><p>和 el data methods 同级,computed 为计算属性</p><h3 id="Axios"><a href="#Axios" class="headerlink" title="Axios"></a>Axios</h3><p>方法类似于Ajax 多了一个params用于传参 和data一样 data用不了就用params</p><p>这个的话 我有点不理解 好像用到了 es6 的语法 </p><p>我干脆抄一段现成的代码下来吧 以后对着改 </p><p>document.querySelector(“#btnPOST”).addEventListener(‘click’,==async== fucntion(){<br>const { data: res } = ==await== axios.post(“URL”,{ JSON })<br>console.log(res)<br>}) </p><h3 id="生命周期"><a href="#生命周期" class="headerlink" title="生命周期"></a>生命周期</h3><ul><li><p>生命周期又名生命周期回调函数、生命周期函数、生命周期钩子</p></li><li><p>它是Vue在关键时刻帮我们调用的一些特殊名称的函数</p></li><li><p>生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的</p></li><li><p>生命周期函数中的this指向是vm 或 组件实例对象</p><img src="https://cn.vuejs.org/assets/lifecycle_zh-CN.W0MNXI0C.png"></li></ul><h5 id="挂载流程"><a href="#挂载流程" class="headerlink" title="挂载流程"></a>挂载流程</h5><p>new一个vue </p><p>然后初始化生命周期和事件</p><blockquote><p>beforeCreate: 但此时数据代理还未开始,无法通过vm访问到data中的数据、methods中的方法</p></blockquote><p>然后初始化数据监测和数据代理</p><blockquote><p>created: 这个时候就可以通过vm访问到data中的数据、methods中的方法</p></blockquote><p>然后Vue开始解析你的模板 </p><blockquote><p>就是你.vue文件中的script,但此时页面还不能显示解析好的内容</p></blockquote><ul><li>会判断有无el,无就看$amount()</li><li>会判断有无template(和直接挂载不同 这个会直接把目标标签也给杀死),无就不管</li></ul><blockquote><p>beforeMount: 此时页面显示的是未经Vue编译的DOM结构</p><p>此时所有对DOM的操作,最终都不奏效</p></blockquote><p>然后Vue 将内存中 虚拟的DOM转化为 真实的DOM 插入页面</p><blockquote><p>mounted: 此时页面中显示的是经过Vue编译的DOM</p><p>对DOM的操作均有效(尽可能避免)。至此初始化过程结束,一般在此开启定时器、发送网络请求、订阅消息、绑定自定义事件等初始化操作</p></blockquote><h5 id="更新流程"><a href="#更新流程" class="headerlink" title="更新流程"></a>更新流程</h5><blockquote><p>此时Vue处于Mounted 挂载中的状态 </p></blockquote><p>当页面数据更新</p><blockquote><p>beforeUpdata: 此时:数据是新的,但页面是旧的,即:页面尚未和数据保持同步。</p></blockquote><p>根据新数据,生成新的虚拟DOM,随后与旧的虚拟DOM进行比较,最终完成页面更新,即:完成了Model => View的更新</p><blockquote><p>updated: 此时:数据是新的,页面也是新的,即:页面和数据保持同步</p></blockquote><h5 id="销毁流程"><a href="#销毁流程" class="headerlink" title="销毁流程"></a>销毁流程</h5><p>当遇见.$destory()时</p><blockquote><p>beforeDestory: 此时vm中的所有的:data、methods、指令等等,都处于可用状态,即将执行销毁过程,一般在此阶段:关闭定时器、取消订阅消息、解绑自定义事件等收尾工作。</p></blockquote><p>然后移出所有的侦听器、子组件、事件监听器</p><h3 id="单页面应用程序"><a href="#单页面应用程序" class="headerlink" title="单页面应用程序"></a>单页面应用程序</h3><p>单页面应用程序 简称 SPA,顾名思义,指的是一个 Web 网站中只有唯一的一个 HTML 页面,所有的功能与交互都在这唯一的一个页面内完成。</p><h3 id="VUE组件"><a href="#VUE组件" class="headerlink" title="VUE组件"></a>VUE组件</h3><p>巧妙了解组件的优点:</p><p>传统方法编写应用</p><ul><li>依赖关系混乱、不好维护</li><li>代码复用率不高</li></ul><blockquote><p>比如你写的一些footer啊之类的 之前的操作就是新建一个页面就复制粘贴HTML 再对应的引用CSS文件和JS文件</p><p>这样就比较混乱 不好管理 而Vue就是为了解决这个的 它是提供一个框架 把做项目所需要用到的都给我们搭建出来</p></blockquote><h5 id="vue组件的三个组成部分"><a href="#vue组件的三个组成部分" class="headerlink" title="vue组件的三个组成部分"></a>vue组件的三个组成部分</h5><p>每个.vue组件都由 3 部分组成,分别是:</p><ul><li>template -> 组件的模板结构</li><li>script -> 组件的JavaScript</li><li>style -> 组件的样式</li></ul><h5 id="组件的父子关系"><a href="#组件的父子关系" class="headerlink" title="组件的父子关系"></a>组件的父子关系</h5><ul><li>组件在被封装好之后,彼此之间是相互独立的,不存在父子关系。</li><li>在使用组件时,根据彼此的嵌套关系,形成了父子关系、兄弟关系。</li></ul><h5 id="使用组件的三个步骤"><a href="#使用组件的三个步骤" class="headerlink" title="使用组件的三个步骤"></a>使用组件的三个步骤</h5><ul><li>使用 import 语法导入需要的组件</li><li>使用 components 节点注册<ul><li>通过 components 注册的是 私有子组件,即在 组件A 的 components 节点下,注册了 组件F 。则 组件F 只能用于 组件A 不能用于 组件C</li></ul></li><li>以 标签形式 使用刚才的注册的组件</li></ul><h5 id="注册全局组件"><a href="#注册全局组件" class="headerlink" title="注册全局组件"></a>注册全局组件</h5><p>在vue项目的 main.js 入口文件中,通过 Vue.component()方法 </p><h5 id="组件的props"><a href="#组件的props" class="headerlink" title="组件的props"></a>组件的props</h5><p>props 是组件的自定义属性,在封装通用组件的时候,合理的使用 props 可以极大的提高组件的复用性</p><h3 id="VUE-CLI-脚手架"><a href="#VUE-CLI-脚手架" class="headerlink" title="VUE-CLI(脚手架)"></a>VUE-CLI(脚手架)</h3><p>cli = command + line + interface.</p><p>vue-cli 是 Vue.js 开发的标准工具。它简化了程序员基于 webpack 创建工程化的 Vue 项目的过程</p><h5 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h5><p>vue cerate 项目的名称</p><h5 id="vue中src目录的构成"><a href="#vue中src目录的构成" class="headerlink" title="vue中src目录的构成"></a>vue中src目录的构成</h5><ul><li>assets 文件夹:存放项目用到的静态资源文件,例如css样式表、图片资源</li><li>components 文件夹:程序员封装的、可复用的组件</li><li>main.js 是项目的入口文件。整个项目的运行,要先执行main.js</li></ul><h5 id="vue项目的运行流程"><a href="#vue项目的运行流程" class="headerlink" title="vue项目的运行流程"></a>vue项目的运行流程</h5><p>在工程化的项目中,vue要做的事情非常单纯:通过main.js 把 App.vue 渲染到 index.html 的指定区域中</p><h5 id="render函数"><a href="#render函数" class="headerlink" title="render函数"></a>render函数</h5><p>在 import vue from ‘vue’ 时,我们会引用到不完整的、残缺的vue文件 (当然vue.js是完整的)</p><p>缺什么呢 缺的就是 模板解析器 (作用就是 把你的东西渲染到主页面上) 这时候就需要render函数来帮忙</p><h5 id="修改默认配置"><a href="#修改默认配置" class="headerlink" title="修改默认配置"></a>修改默认配置</h5><p>在 vue.config.js 里面是可以写对脚手架的默认修改的,具体可以阅读文档</p><h5 id="插件"><a href="#插件" class="headerlink" title="插件"></a>插件</h5><p>在 main.js 同目录下创建,本质是 对象 ,需要使用 install 安装</p><p>使用 Vue.use( 插件名 )</p><h3 id="组件化编码流程(通用)"><a href="#组件化编码流程(通用)" class="headerlink" title="组件化编码流程(通用)"></a>组件化编码流程(通用)</h3><h5 id="实现静态组件"><a href="#实现静态组件" class="headerlink" title="实现静态组件"></a>实现静态组件</h5><p>抽取组件,使用组件实现静态页面效果</p><h3 id="全局事件总线实现"><a href="#全局事件总线实现" class="headerlink" title="全局事件总线实现"></a>全局事件总线实现</h3><p>实现任意组件之间的通信</p><p>安装全局事件总线</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs vue"> new Vue({<br>beforeCreate(){<br>Vue.prototype.$bus = this<br>}<br>})<br></code></pre></td></tr></table></figure><p>使用全局事件总线</p><figure class="highlight autoit"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs autoit">$bus.$emit 传参<br>$bus.$on 接收<br></code></pre></td></tr></table></figure><blockquote><p>EventBus已经弃用,官方文档中推荐使用mitt</p></blockquote><h3 id="插槽"><a href="#插槽" class="headerlink" title="插槽"></a>插槽</h3><h3 id="Vuex"><a href="#Vuex" class="headerlink" title="Vuex"></a>Vuex</h3><p>vuex是专门在Vue中实现集中式状态管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理,也是一种组件间通信的方式,且适用于任意组件间通信</p><p>当多个组件依赖于同一状态,来自不同组件的行为需要变更同一状态时我们启用Vuex</p><h3 id="路由"><a href="#路由" class="headerlink" title="路由"></a>路由</h3><p>一个路由就是一组映射关系</p><p>key 为路径,value 可能是 function 或 component </p><h5 id="路由分类"><a href="#路由分类" class="headerlink" title="路由分类"></a>路由分类</h5><ul><li><p>后端路由:</p><ul><li><p>value 是 function ,用于处理客户端提交的请求。</p></li><li><p>服务器接收到一个请求时</p></li></ul></li><li><p>前端路由:</p><ul><li>value 是 component,用于展示页面。</li><li>当浏览器的路径发生改变时,对应的组件就会显示。</li></ul></li></ul><h5 id="路由的基本使用"><a href="#路由的基本使用" class="headerlink" title="路由的基本使用"></a>路由的基本使用</h5><p>引用 vue-router 组件并新建一个router文件夹用于存放index.js 写路由器</p><p>创建并暴露一个路由器</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs vue">export default new Vue Router({<br>routes:[<br>{<br>path:'/路径',<br>component:组件<br>},<br>{<br>//嵌套路由的话<br>path:'/路径',<br>component:组件,<br>children:[<br>{<br>path:'路径',<br>component:组件<br>}<br>]<br>}<br>]<br>})<br></code></pre></td></tr></table></figure><p>并在点击切换的 a标签 处改为 router-link 并将 href 改为 to=”/路径” 这样的写法</p><h3 id="setup函数"><a href="#setup函数" class="headerlink" title="setup函数"></a>setup函数</h3><p>Vue3中一个新的配置项,值为一个函数。</p><p>setup 是所有Composition API(组合API)</p><p>组件中使用的 数据 方法 皆需要配置在 setup 中</p><p>setup若返回一个对象,则对象中的属性、方法,在模板中均可以直接使用。</p><p>setup尽量不要与Vue2.x配置混用</p><h3 id="ref函数"><a href="#ref函数" class="headerlink" title="ref函数"></a>ref函数</h3><p>传参的时候 如</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">let</span> name = <span class="hljs-keyword">ref</span>(<span class="hljs-string">'张三'</span>)<br><span class="hljs-keyword">let</span> job = <span class="hljs-keyword">ref</span>({<br>type:<span class="hljs-string">'123'</span>,<br>epyt:<span class="hljs-string">"321"</span><br>})<br></code></pre></td></tr></table></figure><p>这个时候就需要用到ref函数 </p><h3 id="reactive函数"><a href="#reactive函数" class="headerlink" title="reactive函数"></a>reactive函数</h3><p>定义一个对象类型的响应式数据(基本类型不用,用<code>ref</code>函数)</p><p>语法 <code>const 代理对象 = reactive(源对象)</code> 接收一个对象(或数组),返回一个代理对象(Proxy对象)</p><p>reactive定义的响应式数据是“深层次”的</p>]]></content>
<summary type="html">经典前端框架之一</summary>
<category term="技术栈" scheme="http://example.com/categories/%E6%8A%80%E6%9C%AF%E6%A0%88/"/>
<category term="前端" scheme="http://example.com/tags/%E5%89%8D%E7%AB%AF/"/>
<category term="笔记" scheme="http://example.com/tags/%E7%AC%94%E8%AE%B0/"/>
<category term="迁移" scheme="http://example.com/tags/%E8%BF%81%E7%A7%BB/"/>
</entry>
<entry>
<title>Postman</title>
<link href="http://example.com/2023/06/24/Postman/"/>
<id>http://example.com/2023/06/24/Postman/</id>
<published>2023-06-24T10:02:02.000Z</published>
<updated>2024-06-24T03:19:35.842Z</updated>
<content type="html"><![CDATA[<h1 id="接口"><a href="#接口" class="headerlink" title="接口"></a>接口</h1><p>接口测试-发什么回什么-><strong><a href="https://postman-echo.com/post">https://postman-echo.com/post</a></strong></p><h3 id="接口简介"><a href="#接口简介" class="headerlink" title="接口简介"></a>接口简介</h3><p>接口:就是软件提供给外部的一种服务。用作数据传输。 在硬件方面USB、投影机被称为接口,在软件方面统称API,如微信的支付和提现。(统称鉴权码,有token、key、appkey)</p><p>内部接口:开发人员自己开发的对自身系统提供的接口</p><p>外部接口:开发系统调用外部的,微信、支付宝,其它的接口</p><p>接口测试的本质:就是测试接口能否正常的交互数据,权限控制以及异常场景。</p><h3 id="软件为什么需要接口"><a href="#软件为什么需要接口" class="headerlink" title="软件为什么需要接口"></a>软件为什么需要接口</h3><p>因为接口能够让内部的数据被外部进行修改</p><h3 id="为什么要做接口测试"><a href="#为什么要做接口测试" class="headerlink" title="为什么要做接口测试"></a>为什么要做接口测试</h3><ul><li>现在很多系统都是前后端分离,开发的进度不一样,需要把一开始开发出来的接口进行测试</li><li>基于安全考虑,前端有验证很容易绕过,直接请求接口</li><li>测试推崇的是测试左移,即尽早测试。</li></ul><h3 id="接口测试的简介和分类"><a href="#接口测试的简介和分类" class="headerlink" title="接口测试的简介和分类"></a>接口测试的简介和分类</h3><p>接口测试就是测试系统组件接口之间的一种测试</p><p>分类:</p><ul><li>测试外部接口:测试被测系统和外部系统之间的接口(只需要测试正例即可)</li><li>测试内部接口:<ul><li>内部接口只提供给内部系统使用。(预算系统,承保系统)(只需要测试正例即可)</li><li>内部接口提供给外部系统使用(测试必须非常全面)</li></ul></li></ul><h3 id="接口测试的流程以及用例的设计"><a href="#接口测试的流程以及用例的设计" class="headerlink" title="接口测试的流程以及用例的设计"></a>接口测试的流程以及用例的设计</h3><ul><li>拿到接口api文档(通过抓包工具获取),熟悉接口业务,接口地址,鉴权方式,入参,码</li><li>编写接口用例以及评审</li><li>使用接口测试工具Postman实现接口测试</li><li>Postman-+Newman+Jenkins实现持续集成,并且输出测试报告并且发送邮件,并且输出测试报告并且发送邮件</li></ul><h3 id="接口返回数据和JSON详解"><a href="#接口返回数据和JSON详解" class="headerlink" title="接口返回数据和JSON详解"></a>接口返回数据和JSON详解</h3><ul><li>json格式:三组数据<ul><li>{error_code:0,msg:”0”,data:[]}</li><li>error_code:错误码</li><li>msg:对错误码的中文说明</li><li>data:真正的返回的数据</li></ul></li><li>jsonj就是一种数据类型,整形,小数,字符串</li><li>JSON由两组数据组成<ul><li>MAP对象,键值对</li><li>数组</li></ul></li></ul><h1 id="Postman界面介绍"><a href="#Postman界面介绍" class="headerlink" title="Postman界面介绍"></a>Postman界面介绍</h1><ul><li>Home主页</li><li>workspaces 工作空间<ul><li>Collections 项目集合</li><li>ApiS api文档</li><li>Environments 全局变量</li><li>Mock Server 虚拟服务器</li><li>Monitors 监听器</li><li>History 历史记录</li></ul></li></ul><h1 id="常见的请求头"><a href="#常见的请求头" class="headerlink" title="常见的请求头"></a>常见的请求头</h1><h3 id="Accept"><a href="#Accept" class="headerlink" title="Accept"></a>Accept</h3><p>常用,它的作用是:客户端接收的数据格式;</p><p>比方说你的参数值填写的是application/json,就说明浏览器所接收的数据是json类型的数据,当你加了Accept请求头之后,你会发现你得到的数据和你没有加Accept请求头的数据是完全不一样的。如果你没有加Accept这个请求头,你得到的数据可能就是一个简单的网页。Accept它可以影响你返回的数据。</p><h3 id="X-Requested-With"><a href="#X-Requested-With" class="headerlink" title="X-Requested-With"></a>X-Requested-With</h3><p>它的作用是:异步请求;</p><p>如果对开发有一定的了解的话,前端里面有这样一个技术Ajax异步请求。现在很多的功能都会用到这个异步请求,比如说登录。</p><p>简单的举个列子:如果现在你想去上海,只有一条路的话,你只能走唯一的一条路。那么如果有两条路或者多条路,可以坐飞机,高铁,汽车等等。那么它们就相当于异步,也就是说你可以通过飞机到上海,也可以坐高铁到上海,这样通俗的理解异步请求。</p><p>异步请求的特点:无刷新。就是说登录的时候是需要进行页面跳转的,而异步请求它不需要跳转也可以做到这样的请求。</p><h3 id="User-Aget"><a href="#User-Aget" class="headerlink" title="User-Aget"></a>User-Aget</h3><p>它的作用是:发送请求的客户端的类型;</p><p>比如说我们可以通过postman去发送请求类型,也可通过浏览器去发送请求等等,那么有的接口你通过非浏览器去请求它是无法通过的</p><h3 id="Content-type"><a href="#Content-type" class="headerlink" title="Content-type"></a>Content-type</h3><p>它的作用是:请求的报文格式;</p><h3 id="Cookie"><a href="#Cookie" class="headerlink" title="Cookie"></a>Cookie</h3><p>Cookie信息;</p><p>有的接口需要登录之后才会生成Cookie信息,必须要保持登录的状态。这种情况我们就需要对Cookie信息进行管理。</p><h1 id="Postman执行接口测试"><a href="#Postman执行接口测试" class="headerlink" title="Postman执行接口测试"></a>Postman执行接口测试</h1><h3 id="请求页签"><a href="#请求页签" class="headerlink" title="请求页签"></a>请求页签</h3><ul><li>Params:get请求传参</li><li>authorization:鉴权</li><li>headers:请求头</li><li>Body:<ul><li>post 请求传参</li><li>none 没有参数</li><li>form-data:既可以传键值对参数也可以传文件</li><li>x-www-from-urlencoded:只能够传键值对参数</li><li>raw:json,text,xml,html,javascript</li><li>binary:把文件以二进制的方式传参</li></ul></li><li>pre-request-script:请求之前的脚本</li><li>tests:请求之后的断言</li><li>cookies:用于管理cookie信息</li></ul><h3 id="响应页签"><a href="#响应页签" class="headerlink" title="响应页签"></a>响应页签</h3><ul><li>Body:接口返回的数据<ul><li>Pretty:以Json、html、XML…不同格式查看返回的数据</li><li>Raw:以文本的方式查看返回的数据</li><li>PreView:以网页的方式查看返回的数据</li></ul></li><li>Cookies:响应的cookies信息</li><li>Headers:响应头</li><li>Test Results:断言的结果</li><li>200是状态码 Ok是状态信息 681MS是响应的时间 343B是响应的字节数</li></ul><h1 id="环境变量和全局变量"><a href="#环境变量和全局变量" class="headerlink" title="环境变量和全局变量"></a>环境变量和全局变量</h1><p>可以在Environments那里设置不同情况的环境</p><p>比如开发环境、测试环境、生成环境</p><p>并且使用来使用你的环境</p><p>比如:https:///路径</p><p>然后再在右上角选择你需要的环境即可</p><p>环境变量:环境变量就是全局变量</p><p>全局变量:全局变量就是能够在任何接口里面访问的变量</p><h1 id="接口关联"><a href="#接口关联" class="headerlink" title="接口关联"></a>接口关联</h1><ul><li>json提取器实现接口关联<ul><li>在请求页签:Tests中使用var 变量名=JSON.parse(responseBody),json提取器将得到数据提取成json格式,这样可以设置一个全局变量,然后使用</li></ul></li><li>使用正则表达式提取器实现接口关联<ul><li>在请求页签:Tests中使用var 变量名=responseBody.match(new RegExp(‘复制Raw并把Value改为(*?)’)),这样可以设置一个全局变量,然后使用(记得是变量名[1])</li></ul></li></ul><h1 id="postman内置动态参数以及自定义的动态参数"><a href="#postman内置动态参数以及自定义的动态参数" class="headerlink" title="postman内置动态参数以及自定义的动态参数"></a>postman内置动态参数以及自定义的动态参数</h1><ul><li> 生成当前时间的时间戳</li><li> 生成0-1000之间的随机数</li><li> 生成速记GUID字符串</li></ul>]]></content>
<summary type="html">接口测试软件</summary>
<category term="工具使用" scheme="http://example.com/categories/%E5%B7%A5%E5%85%B7%E4%BD%BF%E7%94%A8/"/>
<category term="工具" scheme="http://example.com/tags/%E5%B7%A5%E5%85%B7/"/>
<category term="前端" scheme="http://example.com/tags/%E5%89%8D%E7%AB%AF/"/>
<category term="迁移" scheme="http://example.com/tags/%E8%BF%81%E7%A7%BB/"/>
</entry>
<entry>
<title>JavaScript</title>
<link href="http://example.com/2023/06/24/JavaScript/"/>
<id>http://example.com/2023/06/24/JavaScript/</id>
<published>2023-06-24T10:01:53.000Z</published>
<updated>2024-04-28T03:30:15.068Z</updated>
<content type="html"><![CDATA[<h1 id="JavaScript"><a href="#JavaScript" class="headerlink" title="JavaScript"></a>JavaScript</h1><h2 id="JS的作用"><a href="#JS的作用" class="headerlink" title="JS的作用"></a>JS的作用</h2><p>JS本身是一个脚本语言,主要作用于Web,由ECMAScript、DOM、BOM构成。</p><blockquote><p>可以拿来 表单动态校验、网页特效、服务端开发、桌面程序、APP、控制硬件、游戏开发等。</p></blockquote><h2 id="浏览器怎么执行JS"><a href="#浏览器怎么执行JS" class="headerlink" title="浏览器怎么执行JS"></a>浏览器怎么执行JS</h2><ul><li>渲染引擎:用于解析HTML和CSS,俗称内核</li><li>JS引擎:也称为JS解释器。用于读取网页中的JS代码,对其处理后运行。</li></ul><blockquote><p> 浏览器本身并不会执行JS代码,而是通过内置的JS引擎来执行JS代码,JS引擎执行代码时逐行解释每一句源码,然后由计算机去执行,所以JS语言归为脚本语言,会逐行解释执行。</p></blockquote><h1 id="数据类型"><a href="#数据类型" class="headerlink" title="数据类型"></a>数据类型</h1><p>JS时一种弱类型或者说动态的语言,这意味着不用提前声明变量的类型,在程序运行的过程中,类型会被自动锁定。</p><h2 id="Null-类型-amp-Undefined-类型"><a href="#Null-类型-amp-Undefined-类型" class="headerlink" title="Null 类型 & Undefined 类型"></a>Null 类型 & Undefined 类型</h2><p>这俩都只有本身即 <code>null</code> & <code>underfined</code> 。</p><blockquote><p>从概念上讲,<code>undefined</code> 表示<em>值</em>的缺失,<code>null</code> 表示<em>对象</em>的缺失,当某些东西没有值时,该语言通常默认为 <code>undefined</code>。</p></blockquote><h2 id="Boolean-类型"><a href="#Boolean-类型" class="headerlink" title="Boolean 类型"></a>Boolean 类型</h2><p><code>Boolean</code> 类型表示一个逻辑实体并且包括两个值:<code>true</code> 和 <code>false</code>。</p><h2 id="Number-类型"><a href="#Number-类型" class="headerlink" title="Number 类型"></a>Number 类型</h2><p><code>Number</code> 类型能存储±(2^-1074 ~2^1024)之间的浮点数,超过会自动转换为 ±Infinity.</p><blockquote><p>NaN是一种特殊的数值,当目前运算的结果不为数值的时候就会输出NaN</p></blockquote><h2 id="BigInt-类型"><a href="#BigInt-类型" class="headerlink" title="BigInt 类型"></a>BigInt 类型</h2><p><code>BigInt</code>类型在JS中是一个数字的原始值,它可以表示任意大小的整数。使用BigInt可以安全地存储和操作巨大的整数。</p><h2 id="String-类型"><a href="#String-类型" class="headerlink" title="String 类型"></a>String 类型</h2><p>字符串一般可以用来表示任何数据结构。但这并不总是一个好主意。例如,使用一个分隔符,可以模拟一个列表(而 JavaScript 数组可能更适合)。</p><h2 id="Symbol类型"><a href="#Symbol类型" class="headerlink" title="Symbol类型"></a>Symbol类型</h2><p><code>Symbol</code> 是<strong>唯一</strong>并且<strong>不可变</strong>的原始值并且可以用来作为对象属性的键(如下)。在某些程序语言当中,Symbol 也被称作“原子(atom)类型”。symbol 的目的是去创建一个唯一属性键,保证不会与其他代码中的键产生冲突。</p><h2 id="Object-类型"><a href="#Object-类型" class="headerlink" title="Object 类型"></a>Object 类型</h2><p>在JS中,对象是唯一可变的值。</p><blockquote><p>函数也是具有可以被调用能力的对象。</p></blockquote><h1 id="JS基础"><a href="#JS基础" class="headerlink" title="JS基础"></a>JS基础</h1><h2 id="Input-x2F-Output"><a href="#Input-x2F-Output" class="headerlink" title="Input/Output"></a>Input/Output</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs JS"><span class="hljs-comment">//浏览器弹出警示框</span><br><span class="hljs-title function_">alert</span>(<span class="hljs-string">"msg"</span>)<br><span class="hljs-comment">//浏览器控制台打印输出信息---->程序员测试用</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(msg)<br><span class="hljs-comment">//浏览器弹出输入框,用户可以输入--->取到的值是字符串</span><br><span class="hljs-title function_">prompt</span>(info)<br><span class="hljs-comment">//可以打印我们返回的元素对象 更好的查看里面的属性和方法</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">dir</span>(msg)<br></code></pre></td></tr></table></figure><blockquote><p>有趣的是,Hacker有一种方法也是通过I/O,内嵌JS语句对网站或者对主机进行骇入。</p></blockquote><h2 id="正则表达式"><a href="#正则表达式" class="headerlink" title="正则表达式"></a>正则表达式</h2><h3 id="正则表达式概述"><a href="#正则表达式概述" class="headerlink" title="正则表达式概述"></a>正则表达式概述</h3><p>正则表达式是用于匹配字符串中字符组合的模式。在JavaScript中,正则表达式也是对象。</p><h3 id="正则表达式的特点"><a href="#正则表达式的特点" class="headerlink" title="正则表达式的特点"></a>正则表达式的特点</h3><ul><li>灵活性、逻辑性和功能性非常的强。</li><li>可以迅速地用极为简单的方式达到字符串的复杂控制</li><li>对于刚接触的人来说,比较晦涩难懂。</li><li>实际开发中,一般都是直接复制写好的正则表达式,但是要求会使用正则表达式并且根据实际情况修改正则表达式。</li></ul><h3 id="正则表达式的组成"><a href="#正则表达式的组成" class="headerlink" title="正则表达式的组成"></a>正则表达式的组成</h3><p>一个正则表达式可以由简单的字符构成,也可以是简单和特殊字符的组合,其中特殊字符也被称为元字符,在正则表达式中是具有特殊意义的专用符号。</p><p>特殊字符可以参考:MDN</p><h1 id="函数"><a href="#函数" class="headerlink" title="函数"></a>函数</h1><h2 id="函数的使用"><a href="#函数的使用" class="headerlink" title="函数的使用"></a>函数的使用</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">function</span> <span class="hljs-title function_">fuctionName</span>(<span class="hljs-params"></span>){<br> <span class="hljs-keyword">return</span> {<span class="hljs-string">"message"</span>:<span class="hljs-string">"hello"</span>}<br>}<br><span class="hljs-comment">//ECMAScript6</span><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">fuctionName</span> = (<span class="hljs-params"></span>) => {<br> <span class="hljs-keyword">return</span> {<span class="hljs-string">"message"</span>:<span class="hljs-string">"hello"</span>}<br>}<br></code></pre></td></tr></table></figure><h2 id="函数的返回"><a href="#函数的返回" class="headerlink" title="函数的返回"></a>函数的返回</h2><p>如果函数没有返回值就会返回undefined。</p><blockquote><p>在Vue3中,如果在行内使用@click = “functionName”之类的指令,带括号表示需要返回值,不带就是不需要。</p></blockquote><h1 id="对象"><a href="#对象" class="headerlink" title="对象"></a>对象</h1><h2 id="创建对象"><a href="#创建对象" class="headerlink" title="创建对象"></a>创建对象</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs JS"><span class="hljs-keyword">const</span> objectName = {<br><span class="hljs-string">"kid"</span>:<span class="hljs-string">"isme"</span>,<br> <span class="hljs-string">"man"</span>:<span class="hljs-string">"isyou"</span><br>}<br><span class="hljs-comment">//使用New Object,值得一提的是该方法里是什么类型的数据创建出来的就是什么类型。</span><br><span class="hljs-keyword">const</span> objectName = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>({<br> <span class="hljs-string">"kid"</span>:<span class="hljs-string">"isme"</span>,<br> <span class="hljs-string">"man"</span>:<span class="hljs-string">"isyou"</span><br>})<br></code></pre></td></tr></table></figure><h2 id="遍历对象"><a href="#遍历对象" class="headerlink" title="遍历对象"></a>遍历对象</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//for in</span><br><span class="hljs-keyword">for</span>(item <span class="hljs-keyword">in</span> <span class="hljs-title class_">ObjectName</span>){<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(item)<br>}<br><span class="hljs-comment">//Object.keys() 返回属性名数组</span><br><span class="hljs-title class_">Object</span>.<span class="hljs-title function_">keys</span>(<span class="hljs-title class_">ObjectName</span>)<br><span class="hljs-comment">//Object.values() 返回属性值数组</span><br><span class="hljs-title class_">Object</span>.<span class="hljs-title function_">values</span>(<span class="hljs-title class_">ObjectName</span>)<br><span class="hljs-comment">//Object.entries() 返回嵌套数组</span><br><span class="hljs-title class_">Object</span>.<span class="hljs-title function_">entries</span>(<span class="hljs-title class_">ObjectName</span>)<br></code></pre></td></tr></table></figure><h1 id="内置对象"><a href="#内置对象" class="headerlink" title="内置对象"></a>内置对象</h1><ul><li>内置对象就是JS语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)</li><li>内置对象的最大优点就是帮助我们快速开发</li><li>JS提供了多个内置对象:Math、Data、Array、String等</li></ul><h1 id="DOM"><a href="#DOM" class="headerlink" title="DOM"></a>DOM</h1><ul><li>文档对象模型</li><li>DOM就是把文档当作一个对象来看待</li><li>DOM的顶级对象是document</li><li>DOM主要学习的是操作页面元素</li><li>DOM是W3C标准规范</li></ul><p>1.对于JS,为了能够使JS操作HTML,JS就有了一套自己的dom编程接口。</p><p>2.对于HTML,dom使得html形成一棵dom树。包括文档、元素、节点。</p><h2 id="什么是DOM"><a href="#什么是DOM" class="headerlink" title="什么是DOM"></a>什么是DOM</h2><p>文档对象模型(DOM),是一种标准编程接口。W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结果、样式。</p><h2 id="DOM树"><a href="#DOM树" class="headerlink" title="DOM树"></a>DOM树</h2><ul><li>文档:一个页面就是一个文档,DOM中使用document表示</li><li>元素:页面中的所有标签都是元素,DOM中用element表示</li><li>节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM中用node表示</li></ul><p>==DOM把以上内容都看成对象==</p><h2 id="获取元素"><a href="#获取元素" class="headerlink" title="获取元素"></a>获取元素</h2><h3 id="根据ID获取"><a href="#根据ID获取" class="headerlink" title="根据ID获取"></a>根据ID获取</h3><ul><li>样式为:element.getElementById(’id’)</li></ul><h3 id="根据标签名获取"><a href="#根据标签名获取" class="headerlink" title="根据标签名获取"></a>根据标签名获取</h3><ul><li><p>样式为:element.getElementsTagName(’元素’)</p></li><li><p>得到的是对象的集合</p></li><li><p>输出要在元素后面加s</p></li></ul><h3 id="通过HTML5新增的方法获取"><a href="#通过HTML5新增的方法获取" class="headerlink" title="通过HTML5新增的方法获取"></a>通过HTML5新增的方法获取</h3><ul><li>考虑兼容性不可使用</li><li>样式为:element.getElementsClassName(’元素’)//根据类名返回元素对象集合</li><li>样式为:element.querySelector(’选择器’) //根据指定选择器返回第一个元素对象—>比如.什么什么就是类选择器<ul><li>只能返回第一个元素对象</li><li>返回全部的话:element.querySelectorAll(’选择器’)</li></ul></li></ul><h3 id="特殊元素获取"><a href="#特殊元素获取" class="headerlink" title="特殊元素获取"></a>特殊元素获取</h3><ul><li>获取body标签<ul><li>样式element.body;</li></ul></li><li>获取html元素<ul><li>样式element.documentElement;</li></ul></li></ul><h2 id="事件基础"><a href="#事件基础" class="headerlink" title="事件基础"></a>事件基础</h2><h3 id="事件概述"><a href="#事件概述" class="headerlink" title="事件概述"></a>事件概述</h3><p>JS使我们有能力创建动态页面,而事件是可以被JS侦测到的行为</p><p>简单理解:触发—响应机制</p><p>事件由三部分组成: 事件源 事件类型 事件处理程序</p><ul><li>事件源 事件被触发的对象 如 按钮<ul><li>var btn=button.getElementById(‘btn’)</li></ul></li><li>事件类型 如何触发 什么事件 比如鼠标点击(onclick) 还是鼠标经过 还是键盘按下</li><li>事件处理程序 通过一个函数赋值的方式完成<ul><li>btn.onclick=function( ){…..}</li></ul></li></ul><h3 id="执行事件的步骤"><a href="#执行事件的步骤" class="headerlink" title="执行事件的步骤"></a>执行事件的步骤</h3><ul><li>获取事件源</li><li>注册事件(绑定事件)</li><li>添加事件处理程序</li></ul><h3 id="鼠标事件操作"><a href="#鼠标事件操作" class="headerlink" title="鼠标事件操作"></a>鼠标事件操作</h3><ul><li>onclick鼠标点击左键触发。</li><li>onmouseover鼠标经过触发</li><li>onmouseout鼠标离开触发</li><li>onfocus获得鼠标焦点触发</li><li>onblur失去鼠标焦点触发</li><li>onmousemove鼠标移动触发</li><li>onmouseup鼠标弹起触发</li><li>onmousedown鼠标按下触发</li></ul><h2 id="操作元素"><a href="#操作元素" class="headerlink" title="操作元素"></a>操作元素</h2><h3 id="改变元素内容"><a href="#改变元素内容" class="headerlink" title="改变元素内容"></a>改变元素内容</h3><ul><li><p>element.innerText= 可以改变元素内容(不识别html标签)</p></li><li><p>element.innerHTML= 可以改变元素内容(识别html标签)——使用最多</p></li></ul><h3 id="样式属性操作"><a href="#样式属性操作" class="headerlink" title="样式属性操作"></a>样式属性操作</h3><ul><li>element.style=行内样式操作</li><li>element.className=类名样式操作</li></ul><h3 id="改变元素类名"><a href="#改变元素类名" class="headerlink" title="改变元素类名"></a>改变元素类名</h3><ul><li>在JS中想一下子改很多,而且有多个项目要更改时,可以用更改类名。</li><li>正常是element.style修改的样式,但是你可以先定义一个类名是你要修改后的样式,然后写this.className=’该类名’,就可以做到修改了。(会进行覆盖)</li><li>如果想要保留原来的类名,可以用this.className=’原来的类名 该类名’ 这样。</li></ul><h3 id="自定义属性的操作"><a href="#自定义属性的操作" class="headerlink" title="自定义属性的操作"></a>自定义属性的操作</h3><ul><li>获取属性值<ul><li>element.属性 获取属性值</li><li>element.getAttribute(‘属性’);</li></ul></li><li>区别:<ul><li>element.属性 获取内置属性值(元素本身自带的属性)</li><li>element.getAttribute(‘属性’); 主要获得自定义的(标准)我们程序员自定义的属性(没错,属性是可以自定义的)</li></ul></li><li>设置属性值<ul><li>element.属性=“值” 设置内置属性值。</li><li>element.setAttribute(‘属性’,’值’)</li></ul></li></ul><h2 id="节点"><a href="#节点" class="headerlink" title="节点"></a>节点</h2><h3 id="节点概述"><a href="#节点概述" class="headerlink" title="节点概述"></a>节点概述</h3><p>一般的,节点至少拥有nodeType(节点类型)、nodeName(节点名称)、nodeValue(节点值)这三个基本属性。</p><ul><li>元素节点 nodeType 为 1;</li><li>属性节点 nodeType 为 2;</li><li>文本节点 nodeType 为 3(文本节点包含文字、空格、换行等);</li></ul><p><strong>我们在实际开发中,节点操作的主要操作的是元素节点</strong></p><p>为什么要用节点操作呢?</p><p>因为在利用我们节点层次关系获取元素的时候会更简单一些。</p><h3 id="节点层级"><a href="#节点层级" class="headerlink" title="节点层级"></a>节点层级</h3><p>利用DOM树可以把节点划分为不同的层级关系,常见的是父子兄层级关系</p><ul><li>element.parentNode就可以直接代替var …………(得到的是离元素最近的父节点)</li><li>element.childNodes返回包含指定节点的子节点的集合,该集合为即时更新的集合。而且childNodes返回的是所有子节点 包括元素节点、文本节点等等。</li><li>element.children返回所有元素子节点,虽然看着很不兼容,但是各个浏览器都是允许使用的。其中对第一个元素子节点和最后一个子节点有特殊的获取方式:(包括元素节点、文本节点等等)<ul><li>第一个子节点:element.firstChild即为获取第一个子节点。</li><li>最后的子节点:element.lastChild即为获取最后一个子节点。</li><li>第一个元素子节点:element.firstElementChild即为获取第一个元素子节点。(有兼容性问题IE9+支持)</li><li>最后的元素子节点:element.lastElementChild即为获取最后的元素子节点。(有兼容性问题IE9+支持)</li><li>正常开发的写法都是element.children[number]这样。</li></ul></li><li>兄弟节点:<ul><li>下一个兄弟节点:element.nextSibling返回当前元素的下一个兄弟节点,找不到则返回NULL</li><li>上一个兄弟节点:element.previousSibling返回当前元素上一个兄弟节点,找不到则返回null</li><li>下一个元素兄弟节点:element.nextElementSibling返回当前元素的下一个元素兄弟节点(有兼容性问题IE9+支持)</li><li>上一个元素兄弟节点:element.previousElementSibling返回当前元素的上一个元素兄弟节点(有兼容性问题IE9+支持)</li></ul></li></ul><h3 id="节点操作"><a href="#节点操作" class="headerlink" title="节点操作"></a>节点操作</h3><ul><li>创建元素节点:var 节点名字=document.creatElement(‘需要创建的节点’) (innerHTML也可以创建节点,但是innerHTML的原理是拼接字符串,creatElement是创建新节点,所以,creatElement会相对快很多。</li><li>添加元素节点:<ul><li>element.appendChild(child)其中element是父级,child是子级 将一个节点添加到指定父节点的子节点列表末尾,类似于CSS中的after伪元素。</li><li>element.insertBefore(child,指定元素) 将一个节点添加到父节点的指定子节点前面。类似于CSS里面的before伪元素。</li></ul></li><li>删除元素节点:element.remove(需要删除的元素节点);(例如某某元素[])</li><li>克隆元素节点:element.cloneNode(); 复制元素节点,但是复制后需要添加,相当于var name=node.cloneNode(); 然后再使用添加元素节点的知识进行添加。<ul><li>括号为空或为false则为浅拷贝,即只复制节点本身,不copy里面的子节点。</li><li>括号里为ture则为深拷贝,可以复制节点里面的所有东西。</li></ul></li></ul><h3 id="事件高级"><a href="#事件高级" class="headerlink" title="事件高级"></a>事件高级</h3><h4 id="注册事件"><a href="#注册事件" class="headerlink" title="注册事件"></a>注册事件</h4><ul><li><p>注册事件概述:给元素添加事件,称为注册事件或者绑定事件。</p></li><li><p>注册事件有两种方式:传统方式和方法监听注册方式。</p></li><li><p>传统注册方式:</p><ul><li><p>利用on开头的事件onclick</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"alert('hi~')"</span>></span><span class="hljs-tag"></<span class="hljs-name">button</span>></span><br></code></pre></td></tr></table></figure></li><li><p>btn.onclick=function(){}</p></li><li><p>特点注册事件的唯一性</p></li><li><p>同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数。</p></li></ul></li><li><p>方法监听注册方式:</p><ul><li>w3c标准 推荐方法</li><li>addEventListener()它是一个方法</li><li>IE9之前的IE不支持此方法,可使用attachEvent()代替</li><li>特点:同一个元素,同一个事件可以注册多个监听器。</li><li>按注册顺序依次执行。</li></ul></li><li><p>addEventListener事件监听方式</p><ul><li>eventTarget.addEventListener(type,listener[,useCapture])方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,就会触发执行事件处理函数。</li><li>该方法接收三个参数:<ul><li>type:事件类型字符串,比如click,mouseover,注意这里不要带on</li><li>listener:事件处理函数,事件发生时,会调用该监听函数。</li><li>useCapture:可选参数,用于描述事件是冒泡还是捕获,是一个布尔值,默认是false。</li></ul></li></ul></li><li><p>attachEvent事件监听方式(IE9前版本支持)</p><ul><li>eventTarget.attachEvent(eventNameWithOn,callback)方法将指定的监听器注册到eventTarget上,当该对象触发指定的事件时,指定的回调函数就会被执行。</li><li>该方法接受两个函数:<ul><li>eventNameWithOn:事件类型字符串,比如onclick,onmouseover这里要带on</li><li>callback:事件处理函数,当目标触发事件时回调函数被调用。</li></ul></li></ul></li></ul><h4 id="解绑事件"><a href="#解绑事件" class="headerlink" title="解绑事件"></a>解绑事件</h4><ul><li><p>传统注册方式:eventTarget.onclick=null;</p></li><li><p>方法监听注册方式:</p><ul><li><p>eventTargrt.removeEventListener(type,listener[,useCapture]);</p><p>其中listener要写函数的名称,这也就意味着注册的时候也要用函数的名称。</p></li><li><p>eventTargrt.detachEventListener(type,listener[,useCapture]);</p><p>此为IE9前适用</p></li></ul></li></ul><h2 id="DOM事件流"><a href="#DOM事件流" class="headerlink" title="DOM事件流"></a>DOM事件流</h2><p>事件流描述的是从页面中接收事件的顺序。</p><p>事件发生时会在元素节点之间按照待定的顺序传播,这个传播过程即为DOM事件流。</p><p>DOM事件流分为三个阶段:1.捕获阶段。2.当前目标阶段。3.冒泡阶段。</p><ul><li><p>事件冒泡:IE最早提出,事件开始时由最具体的元素接收,然后<strong>逐级上</strong>传到DOM最顶层节点的过程。</p><p>有些事件是没有冒泡的:例如onblur、onfocus、onmouseenter、onmouseleave</p></li><li><p>事件捕获:网景最早提出,由DOM最顶层节点开始,然后<strong>逐级向下</strong>传播到最具体的元素接收过程。</p></li><li><p>结合useCapture,若useCapture为true则为事件捕获,false为事件冒泡</p></li></ul><h2 id="事件对象"><a href="#事件对象" class="headerlink" title="事件对象"></a>事件对象</h2><p>div.onclick=function(event){}</p><p>1.event就是一个事件对象,写到我们侦听函数的小括号里面,当形参来看。即事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象event,他有很多的属性和方法。</p><p>2.事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数。</p><p>3.事件对象是我们事件的一系列相关数据的集合,跟事件相关的,比如鼠标点击里面就包含鼠标的相关信息,鼠标坐标之类的,如果是键盘事件里面就包含的键盘事件的信息,比如判断用户按下了哪个键。</p><p>4.这个事件对象我们可以自己命名 比如event、evt、e(你第一次写的空洞骑士界面音乐盒就是e)</p><p>5.事件对象也有兼容性问题 IE678通过window.event</p><p>兼容性写法e=e||window.event</p><h3 id="事件对象的常见属性和方法"><a href="#事件对象的常见属性和方法" class="headerlink" title="事件对象的常见属性和方法"></a>事件对象的常见属性和方法</h3><ul><li><p>e.target 返回触发事件的对象 标准</p><p>e.target返回的是触发事件的对象(元素) this返回的是绑定事件的对象(元素)如绑定ul但触发的li</p></li><li><p>e.srcElement 返回触发事件的对象 非标准IE6~8使用</p></li><li><p>e.type 返回事件的类型 比如click mouseover不带on</p></li><li><p>e.cancelBubble 该属性阻止冒泡 非标准 IE6~8使用</p></li><li><p>e.stopPropagation 该方法阻止冒泡 标准</p></li><li><p>e.returnValue 该属性阻止默认事件 非标准IE6~8使用 比如不让链接跳转</p></li><li><p>e.preventDefault 该方法阻止默认事件 标准 比如不让链接跳转</p></li></ul><h3 id="事件委托(代理、委派)"><a href="#事件委托(代理、委派)" class="headerlink" title="事件委托(代理、委派)"></a>事件委托(代理、委派)</h3><p>事件委托也称为事件代理,在jQuery里面称为事件委派。</p><ul><li>事件委托的原理:不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响每一个子节点(面试时用得到!!!!!!) </li><li>事件委托的作用:只操作了一次DOM,提高了程序的性能。</li></ul><h2 id="常用的鼠标事件"><a href="#常用的鼠标事件" class="headerlink" title="常用的鼠标事件"></a>常用的鼠标事件</h2><h3 id="常见的鼠标事件"><a href="#常见的鼠标事件" class="headerlink" title="常见的鼠标事件"></a>常见的鼠标事件</h3><ul><li><p>contextmenu是鼠标右键的菜单</p></li><li><p>selectstart是鼠标的选中(拉动的选中)</p></li><li><p>click 单击鼠标左键时发生,如果右键也按下则不会发生。当用户的焦点在按钮上并按了 Enter 键时,同样会触发这个事件</p></li><li><p>mousedown 单击任意一个鼠标按钮时发生</p></li><li><p>mouseout 鼠标指针位于某个元素上且将要移出元素的边界时发生</p></li><li><p>mouseover 鼠标指针移出某个元素到另一个元素上时发生</p></li><li><p>mouseup 松开任意一个鼠标按钮时发生</p></li><li><p>mousemove 鼠标在某个元素上时持续发生</p></li></ul><h3 id="鼠标事件对象"><a href="#鼠标事件对象" class="headerlink" title="鼠标事件对象"></a>鼠标事件对象</h3><ul><li>e.clientX 返回鼠标相对于浏览器窗口可视区的X坐标</li><li>e.clientY 返回鼠标相对于浏览器窗口可视区的Y坐标</li><li>e.pageX 返回鼠标相对于文档页面的X坐标 IE9+支持</li><li>e.pageY 返回鼠标相对于文档页面的Y坐标 IE9+支持</li><li>e.screenX 返回鼠标相对于电脑屏幕的X坐标</li><li>e.screenY 返回鼠标相对于电脑屏幕的Y坐标</li></ul><h3 id="mouseenter和mouseover的区别"><a href="#mouseenter和mouseover的区别" class="headerlink" title="mouseenter和mouseover的区别"></a>mouseenter和mouseover的区别</h3><p>mouseover经过自身盒子会触发,经过子盒子还会触发。</p><p>mouseenter只有经过自身盒子才会触发。(不会冒泡)</p><h2 id="常用的键盘事件"><a href="#常用的键盘事件" class="headerlink" title="常用的键盘事件"></a>常用的键盘事件</h2><h3 id="常用键盘事件"><a href="#常用键盘事件" class="headerlink" title="常用键盘事件"></a>常用键盘事件</h3><ul><li>onkeyup 某个键盘按键被松开时触发</li><li>onkeydown 某个键盘按键被按下时触发</li><li>onkeypress 某个键盘按键被按下时触发 但是不能识别功能键 如ctrl shift 箭头等</li></ul><h3 id="键盘事件对象"><a href="#键盘事件对象" class="headerlink" title="键盘事件对象"></a>键盘事件对象</h3><ul><li>KeyCode 返回键盘按下键的ASCII码值<ul><li>keyup和keydown事件不区分字母大小写,都按照大写来看</li><li>keypress事件区分字母大小写</li></ul></li></ul><h1 id="BOM"><a href="#BOM" class="headerlink" title="BOM"></a>BOM</h1><ul><li>浏览器对象模型</li><li>把浏览器当作一个对象来看待</li><li>BOM的顶级对象是window</li><li>BOM学习的是浏览器窗口交互的一些对象</li><li>BOM是浏览器厂商在各自浏览器上定义的,兼容性较差</li></ul><h2 id="BOM概述"><a href="#BOM概述" class="headerlink" title="BOM概述"></a>BOM概述</h2><p>BOM(Browser Object Model)即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象时window。</p><p>BOM由一系列相关的对象构成,并且每个对象都提供了很多方法和属性。</p><p>BOM缺乏标准,JavaScript语法的标准化组织是ECMA,DOM的标准化组织是W3C</p><h2 id="BOM的构成"><a href="#BOM的构成" class="headerlink" title="BOM的构成"></a>BOM的构成</h2><p>window对象是浏览器的顶级对象,它具有双重角色</p><p>1.它是JS访问浏览器窗口的一个接口</p><p>2.他是一个全局对象。定义在全局作用域中的变量、函数都会变成window对象的属性和方法。</p><p>在调用的时候可以省略window,前面学习的对话框都属于window对象方法,如alert、prompt等</p><h2 id="window对象的常见事件"><a href="#window对象的常见事件" class="headerlink" title="window对象的常见事件"></a>window对象的常见事件</h2><h3 id="窗口加载事件"><a href="#窗口加载事件" class="headerlink" title="窗口加载事件"></a>窗口加载事件</h3><ul><li>window.onload=function(){}</li></ul><p>或者</p><ul><li><p>window.addEventListener(“load”,function(){});</p></li><li><p>window.onload是窗口(页面)加载事件,当文档内容完全加载会触发该事件(包括图像、脚本文件、CSS文件等),就调用的处理函数。</p></li><li><p>document.addEventListener(‘DOMCotentLoaded’,function(){})</p><ul><li>DOMContentLoaded事件触发时,仅当DOM加载完成,不包括样式表、图片、flash等。</li><li>IE9以上才支持</li><li>如果页面的图片很多的话,从用户访问到onload触发可能需要较长时间,交互效果就不能实现,必然影响用户体验,此时用DOMCotentLoaded事件比较合适。</li></ul></li></ul><p>注意:</p><ul><li>有了window.onload就可以把JS代码写到页面元素的上方,因为onload是等页面内容全部加载完毕,再去执行处理函数。</li><li>window.onload传统注册事件方式只能写一次,如果有多个,会以最后一个window.onload为准。(addEventListener则没有限制)</li></ul><h3 id="调整窗口大小事件"><a href="#调整窗口大小事件" class="headerlink" title="调整窗口大小事件"></a>调整窗口大小事件</h3><ul><li>window.onresize=function(){}</li><li>window.addEventListener(“resize”,function(){})</li><li>window.onresize是调整窗口大小加载事件,当触发时就调用的处理函数。<ul><li>只要窗口大小发生像素变化,就会触发这个事件。</li><li>我们经常利用这个事件完成响应式布局。window.innerWidth为当前屏幕的宽度</li></ul></li></ul><h3 id="定时器"><a href="#定时器" class="headerlink" title="定时器"></a>定时器</h3><h4 id="setTimeout-定时器"><a href="#setTimeout-定时器" class="headerlink" title="setTimeout()定时器"></a>setTimeout()定时器</h4><p>window.setTimeout(调用函数,[延迟的毫秒数]); </p><p>setTimeout()方法用于设置一个定时器,在该定时器在定时器到期后会执行调用函数。</p><ul><li>window可以省略</li><li>这个调用函数可以直接写函数,或者写函数名或者采取字符串‘函数名()’三种形式。第三种不推荐。</li><li>延迟的毫秒数省略默认为0,如果写,必须是毫秒。</li><li>因为定时器可能有很多,所以我们经常给定时器赋值一个标识符。</li></ul><h4 id="停止setTimeout-定时器"><a href="#停止setTimeout-定时器" class="headerlink" title="停止setTimeout()定时器"></a>停止setTimeout()定时器</h4><p>window.clearTimeout(timeout ID)</p><ul><li>window可以省略</li><li>里面的参数就是定时器的名字</li></ul><h4 id="setlnterval-定时器"><a href="#setlnterval-定时器" class="headerlink" title="setlnterval()定时器"></a>setlnterval()定时器</h4><p>window.setInterval(调用函数,[延迟的毫秒数]); </p><p>setlnterval()方法重复调用一个函数,每隔这个时间,就去调用一次回调函数。</p><ul><li>window可以省略</li><li>这个调用函数可以直接写函数,或者写函数名或者采取字符串‘函数名()’三种形式。</li><li>延迟的毫秒数省略默认为0,如果写,必须是毫秒。</li><li>因为定时器可能有很多,所以我们经常给定时器赋值一个标识符。</li></ul><h4 id="停止setInterval-定时器"><a href="#停止setInterval-定时器" class="headerlink" title="停止setInterval()定时器"></a>停止setInterval()定时器</h4><p>window.clearInterval(interval ID)</p><ul><li>window可以省略</li><li>里面的参数就是定时器的名字</li></ul><h3 id="this"><a href="#this" class="headerlink" title="this"></a>this</h3><p>this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,一般情况下this的最终指向的是那个调用它的对象</p><ul><li>全局作用域或者普通函数中this指向全局对象window、</li><li>方法调用中谁调用就指向谁</li></ul><h2 id="JS执行机制"><a href="#JS执行机制" class="headerlink" title="JS执行机制"></a>JS执行机制</h2><h3 id="JS是单线程"><a href="#JS是单线程" class="headerlink" title="JS是单线程"></a>JS是单线程</h3><p>Javascript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。这是因为Javascript这门脚本语言诞生的使命所致——Javascript是为处理页面中用户的交互以及操作DOM而诞生的。</p><p>单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是:如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。</p><h3 id="同步和异步"><a href="#同步和异步" class="headerlink" title="同步和异步"></a>同步和异步</h3><p>为了解决这个问题,利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程。于是JS出现了同步和异步。</p><ul><li>同步任务:同步任务都在主线程上执行,形成一个执行栈。</li><li>异步任务:JS的异步是通过回调函数实现的。一般而言,异步事件有以下三种类型:<ul><li>普通事件:如click,resize</li><li>资源加载:如load,error</li><li>定时器:如setInterval,setTimeout</li></ul></li></ul><p>JS 设计之初就是一个单线程的编程语言,单线程的异步编程方式有无需考虑线程同步和资源竞争的问题,从源头上避免了线程切换。</p><h3 id="异步编程"><a href="#异步编程" class="headerlink" title="异步编程"></a>异步编程</h3><p>如果我们需要依次进行多个异步操作,使用回调函数会一层一层的嵌套下去,可读性会变得非常的差,这种情况也叫做“回调地狱”。Promise应运而生。</p><blockquote><p>Fetch函数就是Promise很好的例子,fetch先向目标服务器发送请求,<code>.then()</code>中表示如果服务器返回了,则会执行下面的语句。</p></blockquote><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//举个异步例子</span><br><span class="hljs-title function_">fetch</span>(<span class="hljs-string">"https://...."</span>)<br>.<span class="hljs-title function_">then</span>( <span class="hljs-function">()=></span> { <span class="hljs-comment">//获取到数据之后做什么</span><br>})<br>.<span class="hljs-title function_">catch</span>(<span class="hljs-function">()=></span> { <span class="hljs-comment">//抛出错误后做什么</span><br>})<br>.<span class="hljs-title function_">finally</span>(<span class="hljs-function">()=></span> { <span class="hljs-comment">//异步结束后做什么</span><br>})<br><span class="hljs-comment">//异步中的错误使用.catch() then不会执行。</span><br><span class="hljs-comment">//.finally()是Promise结束时调用无论失败与否,可以做清除工作。</span><br></code></pre></td></tr></table></figure><p>async和await是ES17的语法糖。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//举个例子</span><br><span class="hljs-comment">//async 可以直接用在 function前面用于标记 ,await 只能在 async函数中使用。</span><br><span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">test</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-comment">//可以用await直接获得异步函数的返回值,await过程中还是异步</span><br><span class="hljs-keyword">const</span> res1 = <span class="hljs-keyword">await</span> <span class="hljs-title function_">fetch</span>(<span class="hljs-string">"https://...."</span>)<br> <span class="hljs-keyword">const</span> res2 = <span class="hljs-keyword">await</span> <span class="hljs-title function_">fetch</span>(<span class="hljs-string">"https://...."</span>)<br> <span class="hljs-comment">//如果需要同时异步多个,不然像上面这样就是同步</span><br> <span class="hljs-keyword">const</span> [a,b] = <span class="hljs-keyword">await</span> <span class="hljs-title class_">Promise</span>.<span class="hljs-title function_">all</span>([res1,res2])<br> <span class="hljs-comment">//如果在循环中执行异步操作,是不可以直接调用forEach和map这类方法,还是用for,如果需要循环中每个步骤都异步执行,使用for await</span><br> <span class="hljs-keyword">for</span> <span class="hljs-keyword">await</span> (<span class="hljs-keyword">let</span> test <span class="hljs-keyword">of</span> tests){ }<br>}<br></code></pre></td></tr></table></figure><h3 id="执行机制"><a href="#执行机制" class="headerlink" title="执行机制"></a>执行机制</h3><p>1.先执行执行栈中的同步任务</p><p>2.异步任务放入任务队列</p><p>3.一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。</p><h2 id="location对象"><a href="#location对象" class="headerlink" title="location对象"></a>location对象</h2><h3 id="location对象概述"><a href="#location对象概述" class="headerlink" title="location对象概述"></a>location对象概述</h3><p>window对象给我们提供了一个location属性用于获取或设置窗体的URL,并且可以解析URL。因为这个属性返回的是一个对象,所以我们将这个属性也称为location对象。</p><h3 id="URL"><a href="#URL" class="headerlink" title="URL"></a>URL</h3><p>统一资源定位符(Uniform Resource Locator,URL)是互联网上标准资源的地址。互联网上的每个文件都有唯一的一个URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。</p><p>URL的一般语法格式为:</p><p>protocol://host[:port]/path/[?query]#fragment</p><p>如<a href="http://www.itcast.cn/index.html?name=andy&age=18#link">http://www.itcast.cn/index.html?name=andy&age=18#link</a></p><ul><li>protocol:通信协议 常用的http,ftp,maito</li><li>host:主机(域名)</li><li>port:端口号 可选,省略时使用方案的默认端口 如http的默认端口为80</li><li>path:路径 由0或多个/符号分割开的字符串,一般用来表示主机上的一个目录或文件地址</li><li>query:参数 以键值对的形式,通过&符号分开</li><li>fragment:片段 #后内容常见于锚点 链接</li></ul><h3 id="location对象的属性"><a href="#location对象的属性" class="headerlink" title="location对象的属性"></a>location对象的属性</h3><ul><li>location.href:获取或设置整个URL</li><li>location.host:返回主机(域名)</li><li>location.port:返回端口号 如果未写返回 空字符串</li><li>location.pathname:返回路径</li><li>location.search:返回参数</li><li>location.hash:返回片段 #后面内容</li></ul><h3 id="location对象的方法"><a href="#location对象的方法" class="headerlink" title="location对象的方法"></a>location对象的方法</h3><ul><li>location.assign():跟href一样,可以转跳页面</li><li>location.replace():替换当前页面,因为不记录历史,所以不能后退页面。</li><li>location.reload():重新加载当前页面,相当于刷新按钮或者F5如果参数为true 强制刷新ctrl+f5</li></ul><h2 id="navigator对象"><a href="#navigator对象" class="headerlink" title="navigator对象"></a>navigator对象</h2><p>navigator对象包含有关浏览器的信息,它有很多属性,我们最常用的是userAgent,该属性可以返回由客户机发送的user-agent头部的值。</p><p>下面前端代码可以判断用户哪个终端打开界面,实现转跳:</p><p>if((navigator.userAgent.match(/(phone|pad|pod|iPhone|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|WOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))){</p><p>window.location.href=””; //手机</p><p>}else{<br>window.location.href=””;//电脑</p><p>}</p><h2 id="history对象"><a href="#history对象" class="headerlink" title="history对象"></a>history对象</h2><p>window对象给我们提供了一个history对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中)访问过的URL</p><ul><li>history.back()可以使用后退功能</li><li>history.forward()前进功能</li><li>history.go(参数)前进后退功能 参数如果是1前进一个页面,如果是-1 后退一个页面。</li></ul>]]></content>
<summary type="html">前端三剑客之一</summary>
<category term="技术栈" scheme="http://example.com/categories/%E6%8A%80%E6%9C%AF%E6%A0%88/"/>
<category term="前端" scheme="http://example.com/tags/%E5%89%8D%E7%AB%AF/"/>
<category term="笔记" scheme="http://example.com/tags/%E7%AC%94%E8%AE%B0/"/>
<category term="迁移" scheme="http://example.com/tags/%E8%BF%81%E7%A7%BB/"/>
</entry>
<entry>
<title>JQuery</title>
<link href="http://example.com/2023/06/24/JQuery/"/>
<id>http://example.com/2023/06/24/JQuery/</id>
<published>2023-06-24T10:01:47.000Z</published>
<updated>2024-03-16T11:52:59.656Z</updated>
<content type="html"><![CDATA[<h1 id="JQuery"><a href="#JQuery" class="headerlink" title="JQuery"></a>JQuery</h1><p>但是他已经过时了,不建议去学,了解即可(2024)</p><p><a href="https://jquery.cuishifeng.cn/">jQuery API 中文文档链接</a></p><h3 id="JavaScript库"><a href="#JavaScript库" class="headerlink" title="JavaScript库"></a>JavaScript库</h3><p>即library,是一个封装好的特定的集合(方法和函数)。从封装一大堆函数的角度理解库,就是在这个库中,封装了很多预先定义好的函数在里面,比如动画animate、hide、show。</p><p>简单理解:就是一个JS文件,里面对我们原生的JS代码进行了封装,存放到里面。这样我们可以快速高效的使用封装好的功能。</p><h3 id="jQuery的优点"><a href="#jQuery的优点" class="headerlink" title="jQuery的优点"></a>jQuery的优点</h3><ul><li>轻量级。</li><li>跨浏览器兼容</li><li>链式编程、隐式迭代</li><li>对事件、样式、动画支持,大大简化了DOM操作。</li><li>支持插件扩展开发。有着丰富的第三方插件,例如:树形菜单、日期控件、轮播图等。</li><li>免费开源。</li></ul><h3 id="jQuery的顶级对象"><a href="#jQuery的顶级对象" class="headerlink" title="jQuery的顶级对象$"></a>jQuery的顶级对象$</h3><p>1.$是jQuery的别称,在代码中可以使用jQuery代替它,但一般为了方便都是直接使用。</p><p>2.$是jQuery的顶级对象,相当于原生JavaScript中的window。把元素利用它包装成jQuery对象,就可以调用jQuery的方法。</p><h3 id="jQuery对象和DOM对象"><a href="#jQuery对象和DOM对象" class="headerlink" title="jQuery对象和DOM对象"></a>jQuery对象和DOM对象</h3><p>DOM对象与jQuery对象之间是可以相互转换的。</p><p>因为原生JS比jQuery更大,原生的一些属性和方法jQuery没有给我们封装,想要使用这些属性和方法需要把jQuery对象转换为DOM对象才能使用。</p><ul><li><p>DOM对象转换为jQuery对象</p><ul><li>$(‘div’)</li></ul></li><li><p>jQuery对象转化为DOM对象(两种方式)</p><ul><li>$(‘div’)[index]index是索引号</li><li>$(‘div’).get(index) index是索引号</li></ul></li></ul><h3 id="jQuery选择器"><a href="#jQuery选择器" class="headerlink" title="jQuery选择器"></a>jQuery选择器</h3><h5 id="jQuery基础选择器"><a href="#jQuery基础选择器" class="headerlink" title="jQuery基础选择器"></a>jQuery基础选择器</h5><p>原生JS获取元素的方式有很多、很杂,而且兼容情况不一样,因此jQuery给我们做了封装,使获取元素统一标准。</p><p>$(“选择器”)//里面选择器直接写CSS选择器即可,但要加引号</p><h5 id="jQuery设置样式"><a href="#jQuery设置样式" class="headerlink" title="jQuery设置样式"></a>jQuery设置样式</h5><p>$(“div”).css(“属性”,”值”)</p><h5 id="隐式迭代(重要)"><a href="#隐式迭代(重要)" class="headerlink" title="隐式迭代(重要)"></a>隐式迭代(重要)</h5><p>遍历内部DOM元素(伪数组形式存储)的过程就叫做隐式迭代。</p><p>简单理解:给匹配到的所有元素进行循环遍历,执行相应的方法,而不用我们再进行循环,简化我们的操作,方便我们调用。</p><h5 id="jQuery筛选选择器"><a href="#jQuery筛选选择器" class="headerlink" title="jQuery筛选选择器"></a>jQuery筛选选择器</h5><p>用法如$(“li:first”)</p><ul><li>:first 获取第一个元素</li><li>:last 获取最后一个元素</li><li>:eq(index) 获取到的元素中,选择索引号为2的元素,index从0开始。</li><li>:odd 获取到的元素中,索引号为奇数的元素</li><li>:even 获取到的元素中,索引号为偶数的元素</li></ul><h5 id="jQuery筛选方法"><a href="#jQuery筛选方法" class="headerlink" title="jQuery筛选方法"></a>jQuery筛选方法</h5><p>用法如$(“li”).parent()</p><ul><li>parent() 查找父级</li><li>children(selector) 相当于$(“ul>li”),最近一级(亲儿子)</li><li>find(selector) 相当于$(“ul li”), 后代选择器</li><li>siblings(selector) 查找兄弟节点,不包括自己本身</li><li>nextAll([expr]) 查找当前元素之后所有的同辈元素</li><li>prevAll([expr]) 查找当前元素之前所有的同辈元素</li><li>hasClass(class) 检查当前的元素是否含有某个特定的类,如果有,返回true</li><li>eq(index) 相当于$(“li:eq(2)”),index从0开始.</li></ul><h5 id="链式编程"><a href="#链式编程" class="headerlink" title="链式编程"></a>链式编程</h5><p>链式编程是为了节省代码量,看起来更优雅。</p><h3 id="jQuery样式操作"><a href="#jQuery样式操作" class="headerlink" title="jQuery样式操作"></a>jQuery样式操作</h3><h5 id="操作CSS方法"><a href="#操作CSS方法" class="headerlink" title="操作CSS方法"></a>操作CSS方法</h5><p>jQuery可以使用css方法来修改简单元素样式;也可以操作类,修改多个样式。</p><ul><li>参数只写属性名,则是返回属性值。</li><li>参数是属性名,属性值,逗号分隔,是设置一组样式,属性必须加引号,值如果是数字可以不用跟单位和引号。</li><li>参数可以是对象形式,方便设置多组样式。属性名和属性值用冒号隔开,属性可以不用加引号。如$(“div”).css({width:400,height:400})</li></ul><h5 id="设置类样式方法"><a href="#设置类样式方法" class="headerlink" title="设置类样式方法"></a>设置类样式方法</h5><ul><li>添加类:$(“div”).addClass(“current”);</li><li>移除类:$(“div”).removeClass(“current”);</li><li>切换类:$(“div”).toggleClass(“current”);</li></ul><h5 id="类操作与className区别"><a href="#类操作与className区别" class="headerlink" title="类操作与className区别"></a>类操作与className区别</h5><p>原生JS中className会覆盖元素原先里面的类名</p><p>jQuery里面类操作只是对指定类进行操作,不影响原先的类名。</p><h3 id="jQuery效果"><a href="#jQuery效果" class="headerlink" title="jQuery效果"></a>jQuery效果</h3><h5 id="显示隐藏"><a href="#显示隐藏" class="headerlink" title="显示隐藏"></a>显示隐藏</h5><ul><li><p>显示语法规范:show([speed],[easing],[fn])</p></li><li><p>显示参数:</p><ul><li>参数都可以省略,无动画直接显示</li><li>speed:三种预定速度之一的字符串(“slow”,”normal”,”fast”)或是表示动画时长的毫秒数值</li><li>easing:用于指定切换效果,默认是”swing”</li><li>fn:回调函数,在动画完成时执行的函数,每个元素执行一次。</li></ul></li><li><p>show()</p></li><li><p>hide()</p></li><li><p>toggle()</p></li></ul><h5 id="滑动"><a href="#滑动" class="headerlink" title="滑动"></a>滑动</h5><ul><li><p>滑动语法规范:slideDown([speed],[easing],[fn])</p></li><li><p>滑动参数:</p><ul><li>参数都可以省略,无动画直接显示</li><li>speed:三种预定速度之一的字符串(“slow”,”normal”,”fast”)或是表示动画时长的毫秒数值</li><li>easing:用于指定切换效果,默认是”swing”</li><li>fn:回调函数,在动画完成时执行的函数,每个元素执行一次。</li></ul></li><li><p>slideDown()</p></li><li><p>slideUp()</p></li><li><p>slideToggle()</p></li></ul><h5 id="淡入淡出"><a href="#淡入淡出" class="headerlink" title="淡入淡出"></a>淡入淡出</h5><ul><li><p>淡入淡出语法规范:fadeIn([speed],[easing],[fn])</p></li><li><p>淡入淡出参数:</p><ul><li>参数都可以省略,无动画直接显示</li><li>speed:三种预定速度之一的字符串(“slow”,”normal”,”fast”)或是表示动画时长的毫秒数值</li><li>easing:用于指定切换效果,默认是”swing”</li><li>fn:回调函数,在动画完成时执行的函数,每个元素执行一次。</li></ul></li><li><p>fadeIn()</p></li><li><p>fadeOut()</p></li><li><p>fadeToggle()</p></li><li><p>fadeTo()</p><ul><li>渐进方式调整到指定的不透明度:fadeTo([speed],opacity,[easing],[fn])</li><li>opacity透明度必须写,取值0~1之间。</li><li>speed:三种预定速度之一的字符串(“slow”,”normal”,”fast”)或是表示动画时长的毫秒数值</li><li>easing:用于指定切换效果,默认是”swing”</li><li>fn:回调函数,在动画完成时执行的函数,每个元素执行一次。</li></ul></li></ul><h5 id="自定义动画"><a href="#自定义动画" class="headerlink" title="自定义动画"></a>自定义动画</h5><ul><li>animate(params,[speed],[easing],[fn])</li><li>参数<ul><li>params:想要更改的样式属性,以对象形式传递,必须写。属性名可以不用带引号,如果是复合属性则需要采取驼峰命名法</li><li>speed:三种预定速度之一的字符串(“slow”,”normal”,”fast”)或是表示动画时长的毫秒数值</li><li>easing:用于指定切换效果,默认是”swing”</li><li>fn:回调函数,在动画完成时执行的函数,每个元素执行一次。</li></ul></li></ul><h5 id="事件切换"><a href="#事件切换" class="headerlink" title="事件切换"></a>事件切换</h5><ul><li>hover([over],out);<ul><li>over:鼠标移到元素上要触发的函数(相当于mouseenter)</li><li>out:鼠标移出元素要触发的函数(相当于mouseleave)</li></ul></li></ul><h5 id="动画队列以及停止排队的方法"><a href="#动画队列以及停止排队的方法" class="headerlink" title="动画队列以及停止排队的方法"></a>动画队列以及停止排队的方法</h5><ul><li>动画或效果队列:动画或者效果一旦触发就会执行,如果多次触发,就造成多个动画或者效果排队执行。</li><li>停止排队<ul><li>stop()</li><li>stop()方法用于停止动画或效果</li><li>注意:stop()写到动画或者效果的前面,相当于停止结束上一次的动画。</li></ul></li></ul><h3 id="jQuery属性操作"><a href="#jQuery属性操作" class="headerlink" title="jQuery属性操作"></a>jQuery属性操作</h3><h5 id="设置或获取元素固有属性值prop"><a href="#设置或获取元素固有属性值prop" class="headerlink" title="设置或获取元素固有属性值prop()"></a>设置或获取元素固有属性值prop()</h5><p>所谓元素固有属性就是元素本身自带的属性,比如<a>元素中的href</p><ul><li>获取属性语法:prop(“属性”)</li><li>设置属性语法:prop(“属性”,”属性值”)</li></ul><h5 id="设置或获取元素自定义属性值attr"><a href="#设置或获取元素自定义属性值attr" class="headerlink" title="设置或获取元素自定义属性值attr()"></a>设置或获取元素自定义属性值attr()</h5><p>用户自己给元素添加的属性</p><ul><li>获取属性语法:attr(“属性”) //类似原生getAttribute()</li><li>设置属性语法:attr(“属性”,”属性值”)</li></ul><h3 id="jQuery内容文本值"><a href="#jQuery内容文本值" class="headerlink" title="jQuery内容文本值"></a>jQuery内容文本值</h3><p>主要针对元素的内容还有表单的值操作</p><h5 id="普通元素内容html-(相当于inner-HTML)"><a href="#普通元素内容html-(相当于inner-HTML)" class="headerlink" title="普通元素内容html()(相当于inner HTML)"></a>普通元素内容html()(相当于inner HTML)</h5><p>html()—->获取元素的内容</p><p>html(“内容”)—->设置元素的内容</p><h5 id="普通元素文本内容text-(相当于inner-Text)"><a href="#普通元素文本内容text-(相当于inner-Text)" class="headerlink" title="普通元素文本内容text()(相当于inner Text)"></a>普通元素文本内容text()(相当于inner Text)</h5><p>text()—->获取元素的文本内容</p><p>text(“内容”)—->设置元素的文本内容</p><h5 id="表单的值val-(相当于原生value)"><a href="#表单的值val-(相当于原生value)" class="headerlink" title="表单的值val()(相当于原生value)"></a>表单的值val()(相当于原生value)</h5><p>val()—->获取表单的值</p><p>val(“内容”)—->设置表单的值</p><h3 id="jQuery元素操作"><a href="#jQuery元素操作" class="headerlink" title="jQuery元素操作"></a>jQuery元素操作</h3><p>主要是遍历、创建、添加、删除元素操作。</p><h5 id="遍历元素"><a href="#遍历元素" class="headerlink" title="遍历元素"></a>遍历元素</h5><p>jQuery隐式迭代是对同一类元素做了同样的操作。如果想要给同一类元素做不同操作,就要用到遍历。</p><ul><li>$(“div”).each(function(index,domEle){xxx;})<ul><li>each()方法遍历匹配的每一个元素。主要用DOM处理。</li><li>里面的回调函数有两个参数:index是每一个元素的索引号;domEle是每一个DOM元素对象,不是jQuery对象</li><li>所以要想使用jQuery方法,需要给这个dom元素转换为jQuery对象$(domEle)</li></ul></li></ul><h5 id="创建元素"><a href="#创建元素" class="headerlink" title="创建元素"></a>创建元素</h5><ul><li>$(“<li></li>“)</li><li>动态创建了一个<li></li></ul><h5 id="添加元素"><a href="#添加元素" class="headerlink" title="添加元素"></a>添加元素</h5><ul><li>内部添加<ul><li>element.appent(“内容”) 把内容放入匹配元素后面,类似原生appendChild</li></ul></li><li>外部添加<ul><li>element.after(“内容”)</li><li>element.before(“内容”)</li></ul></li></ul><h5 id="删除元素"><a href="#删除元素" class="headerlink" title="删除元素"></a>删除元素</h5><ul><li>element.remove() //删除匹配的元素</li><li>element.empty() //删除匹配的元素集合中所有的子节点</li><li>element.html(“”) //清空匹配的元素内容</li></ul><h3 id="jQuery尺寸、位置操作"><a href="#jQuery尺寸、位置操作" class="headerlink" title="jQuery尺寸、位置操作"></a>jQuery尺寸、位置操作</h3><h5 id="jQuery尺寸"><a href="#jQuery尺寸" class="headerlink" title="jQuery尺寸"></a>jQuery尺寸</h5><ul><li><p>width()/height()取得匹配元素宽度和高度值 只算width/height</p></li><li><p>innerWidth()/innerHeight()取得匹配元素宽度和高度值 包含padding</p></li><li><p>outerWidth()/outerHeight()取得匹配元素宽度和高度值 包含padding、border</p></li><li><p>outerWidth(true)/outerHeight(true)取得匹配元素宽度和高度值 包含padding、border、margin</p></li><li><p>以上参数为空,则是获取相应值,返回的是数字型</p></li><li><p>如果参数为数字,则是修改相应值</p></li><li><p>参数可以不必写单位</p></li></ul><h5 id="jQuery位置"><a href="#jQuery位置" class="headerlink" title="jQuery位置"></a>jQuery位置</h5><p>位置主要有三个:offset()、position()、scrollTop()/scrollLeft()</p><ul><li>offset()设置或获取元素偏移<ul><li>此方法设置或返回被选元素相当于文档的偏移坐标,跟父级没有关系。</li><li>该方法有两个属性left、top。</li><li>可以设置元素的偏移:offset({top:10,left:10})</li></ul></li><li>position()获取元素偏移<ul><li>position()方法用于被选元素相对于带有定位的父级偏移坐标,如果父级都没有定位,则以文档为标准</li></ul></li><li>scrollTop()/scrollLeft()设置或获取元素被卷去的头部和左侧<ul><li>scrollTop()方法设置或返回被选元素被卷去的头部。</li></ul></li></ul><h3 id="jQuery事件"><a href="#jQuery事件" class="headerlink" title="jQuery事件"></a>jQuery事件</h3><h5 id="单个事件注册"><a href="#单个事件注册" class="headerlink" title="单个事件注册"></a>单个事件注册</h5><ul><li>语法:element.事件(function(){})</li></ul><h5 id="单个事件处理"><a href="#单个事件处理" class="headerlink" title="单个事件处理"></a>单个事件处理</h5><p>事件处理on()绑定事件—->on()方法在匹配元素上绑定一个或多个事件的事件处理函数。</p><p>element.on(events,[selector],fn)</p><ul><li><p>events:一个或多个用空格分隔的事件类型,如”click”或”keydown”</p></li><li><p>selector:元素的子元素选择器。</p></li><li><p>fn:回调函数,即绑定在元素上的侦听函数</p></li><li><p>优势</p><ul><li>一:可以绑定多个事件,多个处理事件处理程序。$(“div”).on({mouseover:function(){},mouseout:function(){}})</li><li>二:可以事件委派操作。事件委派的定义就是,把原来加给子元素身上的事件绑定在父元素身上,就是把事件委派给父元素。</li><li>三:动态创建的元素,click()没有办法绑定事件,on()可以给动态生成的元素绑定事件</li></ul></li></ul><p>off()方法可以移出通过on()方法添加的事件处理程序。</p><p>如果有的事件只想触发一次,可以使用one()来绑定事件</p><h5 id="自动触发事件trigger"><a href="#自动触发事件trigger" class="headerlink" title="自动触发事件trigger()"></a>自动触发事件trigger()</h5><p>有些事件希望自动触发,比如轮播图自动播放功能跟点击右侧按钮一致。可以利用定时器自动触发右侧按钮点击事件,不必鼠标点击触发</p><p>element.trigger(“type”)</p><h3 id="jQuery事件对象"><a href="#jQuery事件对象" class="headerlink" title="jQuery事件对象"></a>jQuery事件对象</h3><p>事件被触发,就会有事件对象的产生。</p><p>阻止默认行为:event.preventDefault() 或者 return false</p><p>阻止冒泡:event.stopPropagation()</p><h3 id="jQuery其他方法"><a href="#jQuery其他方法" class="headerlink" title="jQuery其他方法"></a>jQuery其他方法</h3><h5 id="jQuery对象拷贝"><a href="#jQuery对象拷贝" class="headerlink" title="jQuery对象拷贝"></a>jQuery对象拷贝</h5><p>如果想要把某个对象拷贝给另一个对象使用,此时可以使用$.extend()方法</p><p>$extend([deep],target,object1,[objectn])</p><ul><li>deep:如果设为true为深拷贝,默认为false浅拷贝</li><li>target:要拷贝的目标对象</li><li>object1:待拷贝到的第一个对象</li><li>objectn:待拷贝到的第N个对象</li><li>浅拷贝是把拷贝的对象复杂数据类型中的地址拷贝给目标对象,修改目标对象会影响被拷贝对象。</li></ul><h5 id="jQuery多库共存"><a href="#jQuery多库共存" class="headerlink" title="jQuery多库共存"></a>jQuery多库共存</h5><ul><li><p>问题概述:jQuery使用$作为标识符,随着jQuery的流行,其他js库也会用其作为标识符,这样一起使用会起冲突。</p></li><li><p>客观需求:需要一个解决方案,让jQuery和其他的js库不存在冲突,可以同时存在,这就叫做多库共存。</p></li><li><p>jQuery解决方案:</p><ul><li>把里面的$符号统一改为jQuery,例如jQuery(“div”)</li><li>jQuery变量规定新的名称:$.noConflict()</li></ul></li></ul><h5 id="jQuery插件"><a href="#jQuery插件" class="headerlink" title="jQuery插件"></a>jQuery插件</h5><p>jQuery功能比较有限,想要更复杂的特技效果,可以借助jQuery插件完成。</p><p>注意这些插件也是依赖jQuery来完成的,所以必须要先引入jQuery文件,因此页被称为jQuery插件。</p><ul><li><p>常用网站:</p><ul><li><a href="https://www.jq22.com/">jQuery插件库</a></li><li><a href="https://www.htmleaf.com/">jQuery之家</a></li></ul></li><li><p>jQuery插件使用步骤</p><ul><li>引入相关文件。(jQuery文件和插件文件)</li><li>复制相关html、css、js(调用插件)</li></ul></li><li><p>插件演示</p><ul><li>瀑布流</li><li>懒加载:页面滑动到可视区域,再加载图片。我们使用jQuery插件库EazyLazyLoad。注意,此时的js引入文件和js调用必须写到DOM元素(图片)后面 </li><li>全屏滚动(明日方舟)(fullpage.js):github:<a href="https://github.com/alvarotrigo/fullPage.js">https://github.com/alvarotrigo/fullPage.js</a></li></ul></li><li><p>bootstrap JS插件:bootstrap插件也是依赖于jQuery开发的,因此里面的js插件使用,也必须引入jQuery文件。<a href="https://v3.bootcss.com">Bootstrap中文文档</a></p></li></ul>]]></content>
<summary type="html">一个便于使用的JavaScript库</summary>
<category term="技术栈" scheme="http://example.com/categories/%E6%8A%80%E6%9C%AF%E6%A0%88/"/>
<category term="前端" scheme="http://example.com/tags/%E5%89%8D%E7%AB%AF/"/>
<category term="笔记" scheme="http://example.com/tags/%E7%AC%94%E8%AE%B0/"/>
<category term="迁移" scheme="http://example.com/tags/%E8%BF%81%E7%A7%BB/"/>
</entry>
</feed>