-
Notifications
You must be signed in to change notification settings - Fork 1
/
atom.xml
631 lines (577 loc) · 131 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
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[积叶草堂]]></title>
<subtitle><![CDATA[不卑不亢 踏实进取]]></subtitle>
<link href="/atom.xml" rel="self"/>
<link href="http://iwuly.com/"/>
<updated>2016-11-05T08:55:31.000Z</updated>
<id>http://iwuly.com/</id>
<author>
<name><![CDATA[阳阳、Keraun]]></name>
<email><![CDATA[wuly93@163.com]]></email>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title><![CDATA[从零天梯:一探WebSocket协议]]></title>
<link href="http://iwuly.com/2016/09/06/%E4%BB%8E%E9%9B%B6%E5%A4%A9%E6%A2%AF%E7%B3%BB%E5%88%97/%E4%B8%80%E6%8E%A2WebSocket%E5%8D%8F%E8%AE%AE/"/>
<id>http://iwuly.com/2016/09/06/从零天梯系列/一探WebSocket协议/</id>
<published>2016-09-06T11:33:01.000Z</published>
<updated>2016-11-05T08:55:31.000Z</updated>
<content type="html"><![CDATA[<h3 id="u5199_u5728_u524D_u9762"><a href="#u5199_u5728_u524D_u9762" class="headerlink" title="写在前面"></a>写在前面</h3><p>一次偶然的机会,我被派往北京出差,去支援在一线浴血奋战的战友。项目涉及WebSocket,用来实现WEB浏览器和打印驱动之间的双向通信。开始编码之前,我收集了有关WebSocket的资料,甚至去阅读了相关的<a href="https://tools.ietf.org/html/rfc6455" target="_blank" rel="external">RFC文档</a>。阅读资料的同时,我整理了相关笔记,希望给阅读者带来一些帮助~好啦,让我们开始阅读正文吧~<br><a id="more"></a></p>
<h3 id="1-_WebSocket_u51E0_u95EE"><a href="#1-_WebSocket_u51E0_u95EE" class="headerlink" title="1. WebSocket几问"></a>1. WebSocket几问</h3><p>如果你之前对WebSocket协议有些了解,那么可以尝试回答以下问题:</p>
<ol>
<li>WebSocket是什么东西?</li>
<li>数据传输时,WebSocket是否真的实时?</li>
<li>WebSocket底层本质是什么?轮询?</li>
<li>它和HTTP长连接有什么不同?</li>
<li>它的传输过程是什么样子的呢?</li>
</ol>
<p>如果你才刚接触WebSocket协议,不妨可以先通读全文~</p>
<h3 id="2-_WebSocket_u524D_u4E16_u4ECA_u751F"><a href="#2-_WebSocket_u524D_u4E16_u4ECA_u751F" class="headerlink" title="2. WebSocket前世今生"></a>2. WebSocket前世今生</h3><h4 id="2-1_WebSocket_u662F_u4EC0_u4E48_3F"><a href="#2-1_WebSocket_u662F_u4EC0_u4E48_3F" class="headerlink" title="2.1 WebSocket是什么?"></a>2.1 WebSocket是什么?</h4><p><a href="https://tools.ietf.org/html/rfc6455" target="_blank" rel="external"><strong>RFC6455</strong></a>对WebSocket有如下定义:</p>
<pre><code>The WebSocket Protocol enables two-way communication between a client
running untrusted code in a controlled environment to a remote host
that has opted-in to communications from that code.
</code></pre><p>又如<a href="http://baike.baidu.com/link?url=-8Het6X6WDmi1iwfLtg4M3dMtstrCf0eVEXNQArwJFiITGPPlke_MIr8hvoTNIqHNLOVxjqTjxceb5BTFyg_rzMjCoz9F9htS_zanKFxws7" target="_blank" rel="external"><strong>百度百科</strong></a>上的介绍,我们就有了对WebSocket的第一印象:</p>
<ol>
<li>WebSocket protocol 是HTML5一种新的协议。(<strong>是什么</strong>)</li>
<li>它实现了浏览器与服务器全双工通信 (full-duplex)(<strong>功能</strong>)</li>
<li>可以让服务器可以主动传送数据给客户端(<strong>优点</strong>)</li>
<li>利用HTTP协议来完成一部分握手(<strong>与HTTP协议关系</strong>)</li>
</ol>
<h4 id="2-3_WebSocket_u80CC_u666F"><a href="#2-3_WebSocket_u80CC_u666F" class="headerlink" title="2.3 WebSocket背景"></a>2.3 WebSocket背景</h4><p>由于历史原因,在创建一个具有双向通信机制的 web 应用程序时,需要利用到 HTTP 轮询的方式。围绕轮询产生了 “短轮询” 和 “长轮询”。</p>
<ul>
<li><strong>轮询</strong>:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接。</li>
<li><strong>长轮询</strong>:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。</li>
</ul>
<p>用AJAX的long-polling来模拟WebSocket在业界已经有一段时间了。它是一个可行的技术,但它不能优化发送的信息。也就是说,它是一个解决方案,但不是最佳的技术方案。</p>
<p>如果您这部分感兴趣,可以移步我整理的另一篇文章-><a href="http://iwuly.com/2016/01/20/从零天梯系列/web实时通信与跨文档通信/"><strong>web实时通信与跨文档通信</strong></a></p>
<h3 id="3-_WebSocket_u673A_u5236"><a href="#3-_WebSocket_u673A_u5236" class="headerlink" title="3. WebSocket机制"></a>3. WebSocket机制</h3><p>以下简要介绍一下 WebSocket 的原理及运行机制。</p>
<p>WebSocket 是 HTML5 一种新的协议。它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯,它建立在 TCP 之上,同 HTTP 一样通过 TCP 来传输数据,但是它和 HTTP 最大不同是:</p>
<ul>
<li><p>WebSocket 是一种双向通信协议,在建立连接后,WebSocket 服务器和 Browser/Client Agent 都能主动的向对方发送或接收数据,就像 Socket 一样;</p>
</li>
<li><p>WebSocket 需要类似 TCP 的客户端和服务器端通过握手连接,连接成功后才能相互通信。</p>
</li>
</ul>
<p>非 WebSocket 模式传统 HTTP 客户端与服务器的交互如下图所示:</p>
<p>图 1. 传统 HTTP 请求响应客户端服务器交互图<br><img src="/images/lunxun.png" alt="传统 HTTP 请求响应客户端服务器交互图"></p>
<p>使用 WebSocket 模式客户端与服务器的交互如下图:</p>
<p>图 2.WebSocket 请求响应客户端服务器交互图<br><img src="/images/websocket.png" alt="WebSocket 请求响应客户端服务器交互图"></p>
<p>上图对比可以看出,相对于传统 HTTP 每次请求-应答都需要客户端与服务端建立连接的模式,WebSocket 是类似 Socket 的 TCP 长连接的通讯模式,一旦 WebSocket 连接建立后,后续数据都以帧序列的形式传输。在客户端断开 WebSocket 连接或 Server 端断掉连接前,不需要客户端和服务端重新发起连接请求。在海量并发及客户端与服务器交互负载流量大的情况下,极大的节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接受消息是在同一个持久连接上发起,实时性优势明显。</p>
<p>我们再通过客户端和服务端交互的报文看一下 WebSocket 通讯与传统 HTTP 的不同:</p>
<p>在客户端,new WebSocket 实例化一个新的 WebSocket 客户端对象,连接类似 ws://yourdomain:port/path 的服务端 WebSocket URL,WebSocket 客户端对象会自动解析并识别为 WebSocket 请求,从而连接服务端端口,执行双方握手过程,客户端发送数据格式类似:</p>
<p>清单 1.WebSocket 客户端连接报文<br><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><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">GET /webfin/websocket/ HTTP/1.1</span><br><span class="line">Host: localhost</span><br><span class="line">Upgrade: websocket</span><br><span class="line">Connection: Upgrade</span><br><span class="line">Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg==</span><br><span class="line">Origin: http://localhost:8080</span><br><span class="line">Sec-WebSocket-Version: 13</span><br></pre></td></tr></table></figure></p>
<p>可以看到,客户端发起的 WebSocket 连接报文类似传统 HTTP 报文,”Upgrade:websocket”参数值表明这是 WebSocket 类型请求,“Sec-WebSocket-Key”是 WebSocket 客户端发送的一个 base64 编码的密文,要求服务端必须返回一个对应加密的“Sec-WebSocket-Accept”应答,否则客户端会抛出“Error during WebSocket handshake”错误,并关闭连接。</p>
<p>服务端收到报文后返回的数据格式类似:</p>
<p>清单 2.WebSocket 服务端响应报文<br><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><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">HTTP/1.1 101 Switching Protocols</span><br><span class="line">Upgrade: websocket</span><br><span class="line">Connection: Upgrade</span><br><span class="line">Sec-WebSocket-Accept: K7DJLdLooIwIG/MOpvWFB3y3FE8=</span><br></pre></td></tr></table></figure></p>
<p>“Sec-WebSocket-Accept”的值是服务端采用与客户端一致的密钥计算出来后返回客户端的,“HTTP/1.1 101 Switching Protocols”表示服务端接受 WebSocket 协议的客户端连接,经过这样的请求-响应处理后,客户端服务端的 WebSocket 连接握手成功, 后续就可以进行 TCP 通讯了。读者可以查阅WebSocket 协议栈了解 WebSocket 客户端和服务端更详细的交互数据格式。</p>
<p>在开发方面,WebSocket API 也十分简单,我们只需要实例化 WebSocket,创建连接,然后服务端和客户端就可以相互发送和响应消息,在下文 WebSocket 实现及案例分析部分,可以看到详细的 WebSocket API 及代码实现。</p>
<h3 id="4-_WebSocket_u5B9E_u6218"><a href="#4-_WebSocket_u5B9E_u6218" class="headerlink" title="4. WebSocket实战"></a>4. WebSocket实战</h3><p>只专注于客户端的API,因为每个服务器端语言有自己的API。下面的代码片段是打开一个连接,为连接创建事件监听器,断开连接,消息时间,发送消息返回到服务器,关闭连接。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 创建一个Socket实例</span></span><br><span class="line"><span class="keyword">var</span> socket = <span class="keyword">new</span> WebSocket(<span class="string">'ws://localhost:8080'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 打开Socket</span></span><br><span class="line">socket.onopen = <span class="function"><span class="keyword">function</span>(<span class="params">event</span>) </span>{</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 发送一个初始化消息</span></span><br><span class="line"> socket.send(<span class="string">'I am the client and I\'m listening!'</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 监听消息</span></span><br><span class="line"> socket.onmessage = <span class="function"><span class="keyword">function</span>(<span class="params">event</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'Client received a message'</span>,event);</span><br><span class="line"> };</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 监听Socket的关闭</span></span><br><span class="line"> socket.onclose = <span class="function"><span class="keyword">function</span>(<span class="params">event</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'Client notified socket has closed'</span>,event);</span><br><span class="line"> };</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 关闭Socket....</span></span><br><span class="line"> <span class="comment">//socket.close()</span></span><br><span class="line">};</span><br></pre></td></tr></table></figure>
<p>让我们来看看上面的初始化片段。参数为URL,ws表示WebSocket协议。onopen、onclose和onmessage方法把事件连接到Socket实例上。每个方法都提供了一个事件,以表示Socket的状态。</p>
<p>onmessage事件提供了一个data属性,它可以包含消息的Body部分。消息的Body部分必须是一个字符串,可以进行序列化/反序列化操作,以便传递更多的数据。</p>
<h3 id="5-__u53C2_u8003_u6587_u6863"><a href="#5-__u53C2_u8003_u6587_u6863" class="headerlink" title="5. 参考文档"></a>5. 参考文档</h3><p><a href="http://www.cnblogs.com/wei2yi/archive/2011/03/23/1992830.html" target="_blank" rel="external">认识HTML5的WebSocket</a><br><a href="https://en.wikipedia.org/wiki/WebSocket" target="_blank" rel="external">维基:WebSocket</a><br><a href="https://tools.ietf.org/html/rfc6455" target="_blank" rel="external">RFC6455</a><br><a href="http://www.jianshu.com/p/867274a5e054" target="_blank" rel="external">WebSocket 协议 1~4 节</a><br><a href="http://www.jianshu.com/p/fc09b0899141" target="_blank" rel="external">WebSocket 协议 5~10 节</a><br><a href="http://blog.phpha.com/backup/archives/1668.html" target="_blank" rel="external">基于WEB的实时通信方案</a><br><a href="http://www.jianshu.com/p/0e5b946880b4" target="_blank" rel="external">刨根问底HTTP和WebSocket协议</a><br><a href="http://blog.csdn.net/milado_nju/article/details/9255563" target="_blank" rel="external">理解WebKit和Chromium: Chromium网络栈</a><br><a href="http://www.ibm.com/developerworks/cn/java/j-lo-WebSocket/index.html" target="_blank" rel="external">WebSocket 实战</a><br><a href="https://www.zhihu.com/question/19876749" target="_blank" rel="external">知乎:长连接与长轮询分别如何实现的?各有哪些优势和劣势?</a><br><a href="http://www.zhihu.com/question/20215561" target="_blank" rel="external">知乎:WebSocket 是什么原理?为什么可以实现持久连接?</a></p>
]]></content>
<summary type="html">
<![CDATA[<h3 id="u5199_u5728_u524D_u9762"><a href="#u5199_u5728_u524D_u9762" class="headerlink" title="写在前面"></a>写在前面</h3><p>一次偶然的机会,我被派往北京出差,去支援在一线浴血奋战的战友。项目涉及WebSocket,用来实现WEB浏览器和打印驱动之间的双向通信。开始编码之前,我收集了有关WebSocket的资料,甚至去阅读了相关的<a href="https://tools.ietf.org/html/rfc6455">RFC文档</a>。阅读资料的同时,我整理了相关笔记,希望给阅读者带来一些帮助~好啦,让我们开始阅读正文吧~<br>]]>
</summary>
<category term="HTTP" scheme="http://iwuly.com/tags/HTTP/"/>
<category term="WebSocket" scheme="http://iwuly.com/tags/WebSocket/"/>
<category term="通信" scheme="http://iwuly.com/tags/%E9%80%9A%E4%BF%A1/"/>
</entry>
<entry>
<title><![CDATA[一年回忆录]]></title>
<link href="http://iwuly.com/2016/07/01/%E7%94%9F%E6%B4%BB%E7%82%B9%E6%BB%B4/%E4%B8%80%E5%B9%B4%E5%9B%9E%E5%BF%86%E5%BD%95/"/>
<id>http://iwuly.com/2016/07/01/生活点滴/一年回忆录/</id>
<published>2016-07-01T11:16:07.000Z</published>
<updated>2016-10-09T09:47:34.000Z</updated>
<content type="html"><![CDATA[<p>几天前刷朋友圈,看到16届同学陆续开始晒毕业照了,掐指一算,发现我已经工作一年了,不禁老泪纵横。曾仗着自己还年轻,经常宅不出户,晚上熬夜,白天躺尸,作息时间很不稳定。有小伙伴戏谑,“你这是宅懒废”。嗯,他说的好有道理,我竟然无言以对(///ω///)。时间对于每个人都是公平合理的,虚度一天,就少了一天。于是我慌了,担心自己一事无成,所以每天都不敢懈怠。</p>
<a id="more"></a>
<p>回顾过去,自己确实成长了不少。</p>
<p>我在大学期间资质平平,如果不算上奖学金和班干经验,确实没有什么突出的成绩。毕业前参加阿里、网易的校招均被刷掉了,所以我选择先就业再择业的策略,期望在温饱的前提下挤出时间学习,填补知识的空白。这期间我完成了从学生思维到职业思维的转变,并且时时刻刻保持空杯心态。</p>
<p>那会儿被前端技术分享氛围深深感染到了,不辞辛劳不远万里去参加各种分享会,那份渴望至今还记忆犹新。第一次见到传说中的xx大牛,近在咫尺却也不敢上前对话,只能投以深情的目光,那种感觉至今也还萦绕心间。简单说就是“步入社会”了。</p>
<p>工作看似稳定后,当时的我一直在思考另外一个问题,薪水月光的我,几年后如何能在杭州这个城市落脚。因为自己老大不小了,不能再像个孩子任性,所以留给我的时间并不多。</p>
<p>考虑再三,想了个稳妥的方案,加入一家已经成熟的创业公司。一方面公司已经相对稳定,发得起工资,另一方面前途也不错。就是我现在任职的公司了,我感觉这是一个正确的选择。</p>
<p>之后我的工作是很充实的,看到了更大的世界,知道了大前端都是怎么搞的。一开始有专人带着,后来又跟同事频繁接触交流,成长很快。尤其是团队的内部分享,以及邀请行业大牛来公司分享,收获颇丰。在周老大的影响下,我的思考方式也发生变化,以前不求甚解的知识现在也必须搞明白,并且更多的从项目整体上,不光是技术思维,包括产品、运营等角度来考虑问题,清楚自己做的功能价值点在哪里。</p>
<p>不过也有尴尬的一面,由于公司业务增长很快,我的大部分时间还是扑在了业务上,所以能腾出来做知识整理的时间就很少,以后也会慢慢来找一个平衡点。</p>
<p>总之现在的状态我还是挺享受的,脚踏实地的同时,告诉自己,要努力成为一个有趣的人。</p>
]]></content>
<summary type="html">
<![CDATA[<p>几天前刷朋友圈,看到16届同学陆续开始晒毕业照了,掐指一算,发现我已经工作一年了,不禁老泪纵横。曾仗着自己还年轻,经常宅不出户,晚上熬夜,白天躺尸,作息时间很不稳定。有小伙伴戏谑,“你这是宅懒废”。嗯,他说的好有道理,我竟然无言以对(///ω///)。时间对于每个人都是公平合理的,虚度一天,就少了一天。于是我慌了,担心自己一事无成,所以每天都不敢懈怠。</p>]]>
</summary>
<category term="成长" scheme="http://iwuly.com/tags/%E6%88%90%E9%95%BF/"/>
</entry>
<entry>
<title><![CDATA[从零天梯:JS练习题整理]]></title>
<link href="http://iwuly.com/2016/03/01/%E4%BB%8E%E9%9B%B6%E5%A4%A9%E6%A2%AF%E7%B3%BB%E5%88%97/JS%E7%BB%83%E4%B9%A0%E9%A2%98%E6%95%B4%E7%90%86/"/>
<id>http://iwuly.com/2016/03/01/从零天梯系列/JS练习题整理/</id>
<published>2016-03-01T13:05:54.000Z</published>
<updated>2016-11-05T01:56:40.000Z</updated>
<content type="html"><![CDATA[<p>近期在学习JS基础的时候,整理了一些相对典型的JS练习题,有助于更好的理解JS相关概念。<br>欢迎在评论区留下你的答案~~我会不定期更新文章内容</p>
<a id="more"></a>
<h3 id="1-_u4F20_u503C_u548C_u4F20_u5740"><a href="#1-_u4F20_u503C_u548C_u4F20_u5740" class="headerlink" title="1.传值和传址"></a>1.传值和传址</h3><h4 id="1-1"><a href="#1-1" class="headerlink" title="1.1"></a>1.1</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">creat</span>(<span class="params">num</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> num;</span><br><span class="line"> }</span><br><span class="line">} </span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> arr = [creat(<span class="number">0</span>),creat(<span class="number">1</span>),creat(<span class="number">2</span>)];</span><br><span class="line"><span class="built_in">console</span>.log(arr[<span class="number">0</span>]()); </span><br><span class="line"><span class="built_in">console</span>.log(arr[<span class="number">1</span>]()); </span><br><span class="line"><span class="built_in">console</span>.log(arr[<span class="number">2</span>]());</span><br></pre></td></tr></table></figure>
<h4 id="1-2"><a href="#1-2" class="headerlink" title="1.2"></a>1.2</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">var</span> b = {</span><br><span class="line"> k: <span class="number">30</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> c = {</span><br><span class="line"> v: <span class="number">30</span></span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">test</span>(<span class="params">a,b,c</span>) </span>{</span><br><span class="line"> a = <span class="number">2</span>;</span><br><span class="line"> b.k = <span class="number">32</span>;</span><br><span class="line"> c = {</span><br><span class="line"> a: <span class="number">20</span></span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">test(a,b,c);</span><br><span class="line"><span class="built_in">console</span>.log(a);</span><br><span class="line"><span class="built_in">console</span>.log(b.k);</span><br><span class="line"><span class="built_in">console</span>.log(c.a);</span><br></pre></td></tr></table></figure>
<h3 id="2-_u53D8_u91CF_u63D0_u5347"><a href="#2-_u53D8_u91CF_u63D0_u5347" class="headerlink" title="2.变量提升"></a>2.变量提升</h3><h4 id="2-1"><a href="#2-1" class="headerlink" title="2.1"></a>2.1</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span>(!(<span class="string">'userName'</span> <span class="keyword">in</span> <span class="built_in">window</span>)) {</span><br><span class="line"> <span class="keyword">var</span> userName = <span class="string">'test'</span>;</span><br><span class="line">}</span><br><span class="line"><span class="built_in">console</span>.log(userName);</span><br></pre></td></tr></table></figure>
<h4 id="2-2"><a href="#2-2" class="headerlink" title="2.2"></a>2.2</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="number">25</span>;</span><br><span class="line">+<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">a</span>(<span class="params"></span>) </span>{}</span><br><span class="line"> <span class="keyword">var</span> a = <span class="number">20</span>;</span><br><span class="line"> <span class="built_in">console</span>.log(a); </span><br><span class="line">}();</span><br></pre></td></tr></table></figure>
<h4 id="2-3"><a href="#2-3" class="headerlink" title="2.3"></a>2.3</h4><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">test</span>(<span class="params"></span>) </span>{}</span><br><span class="line"><span class="keyword">var</span> test = <span class="number">1</span>;</span><br><span class="line"><span class="built_in">console</span>.log(test);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> go2 = <span class="number">50</span>;</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">go2</span>(<span class="params"></span>) </span>{ }</span><br><span class="line"><span class="built_in">console</span>.log(go2);</span><br></pre></td></tr></table></figure>
<h4 id="2-4"><a href="#2-4" class="headerlink" title="2.4"></a>2.4</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">+<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> a = <span class="number">5</span>;</span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">a</span>(<span class="params"></span>) </span>{};</span><br><span class="line"> <span class="built_in">console</span>.log(a);</span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">b</span>(<span class="params"></span>) </span>{}</span><br><span class="line"> b = <span class="number">6</span>;</span><br><span class="line"> <span class="built_in">console</span>.log(b);</span><br><span class="line"> <span class="keyword">var</span> c = d = b;</span><br><span class="line">}();</span><br><span class="line"><span class="built_in">console</span>.log(d);</span><br><span class="line"><span class="built_in">console</span>.log(c);</span><br></pre></td></tr></table></figure>
<h3 id="3-_u95ED_u5305_u3001_u4F5C_u7528_u57DF_u3001this_u3001prototype"><a href="#3-_u95ED_u5305_u3001_u4F5C_u7528_u57DF_u3001this_u3001prototype" class="headerlink" title="3.闭包、作用域、this、prototype"></a>3.闭包、作用域、this、prototype</h3><h4 id="3-1"><a href="#3-1" class="headerlink" title="3.1"></a>3.1</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span>; i < <span class="number">3</span>; i++) {</span><br><span class="line"> setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(i);</span><br><span class="line"> },<span class="number">0</span>);</span><br><span class="line">}</span><br><span class="line"><span class="built_in">console</span>.log(i);</span><br></pre></td></tr></table></figure>
<h4 id="3-2"><a href="#3-2" class="headerlink" title="3.2"></a>3.2</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> name = <span class="string">"World"</span>;</span><br><span class="line">(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'name:'</span>,name);</span><br><span class="line"> <span class="keyword">if</span>(name === <span class="string">'undefined'</span>) {</span><br><span class="line"> <span class="keyword">var</span> name = <span class="string">"jack"</span>;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">"goodbye "</span> + name);</span><br><span class="line"> }<span class="keyword">else</span> {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">"hello "</span> + name);</span><br><span class="line"> }</span><br><span class="line">})();</span><br></pre></td></tr></table></figure>
<h4 id="3-3"><a href="#3-3" class="headerlink" title="3.3"></a>3.3</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">this</span>.a = <span class="number">20</span>;</span><br><span class="line"><span class="keyword">var</span> test = {</span><br><span class="line"> a: <span class="number">40</span>,</span><br><span class="line"> getName: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> a;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> fn = test.getName;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(fn());</span><br><span class="line"><span class="built_in">console</span>.log(test.getName());</span><br></pre></td></tr></table></figure>
<h4 id="3-4"><a href="#3-4" class="headerlink" title="3.4"></a>3.4</h4><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">this</span>.a = <span class="number">20</span>;</span><br><span class="line"><span class="keyword">var</span> test = {</span><br><span class="line"> a: <span class="number">40</span>,</span><br><span class="line"> init: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">go</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="keyword">this</span>.a);</span><br><span class="line"> }</span><br><span class="line"> go.prototype.a = <span class="number">50</span>;</span><br><span class="line"> <span class="keyword">return</span> go;</span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> p = test.init();</span><br><span class="line">p();</span><br><span class="line"><span class="keyword">new</span>(test.init())();</span><br></pre></td></tr></table></figure>
<h4 id="3-5"><a href="#3-5" class="headerlink" title="3.5"></a>3.5</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">this</span>.a = <span class="number">20</span>;</span><br><span class="line"><span class="keyword">var</span> test = {</span><br><span class="line"> a: <span class="number">40</span>,</span><br><span class="line"> init: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">this</span>.a = <span class="number">30</span>;</span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">go</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">this</span>.a = <span class="number">60</span>;</span><br><span class="line"> }</span><br><span class="line"> go.prototype.a = <span class="number">50</span>;</span><br><span class="line"> go.prototype.info = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="keyword">this</span>.a);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> go;</span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> p = test.init();</span><br><span class="line">p();</span><br><span class="line">(<span class="keyword">new</span>(test.init())).info();</span><br></pre></td></tr></table></figure>
<h4 id="3-6"><a href="#3-6" class="headerlink" title="3.6"></a>3.6</h4><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">this</span>.a = <span class="number">20</span>;</span><br><span class="line"><span class="keyword">var</span> test = {</span><br><span class="line"> a: <span class="number">40</span>,</span><br><span class="line"> init: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">go</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="keyword">this</span>.a);</span><br><span class="line"> }</span><br><span class="line"> go.prototype.a = <span class="number">50</span>;</span><br><span class="line"> <span class="keyword">return</span> go;</span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> p = test.init();</span><br><span class="line">p();</span><br><span class="line"><span class="keyword">new</span>(test.init())();</span><br></pre></td></tr></table></figure>
<h4 id="3-7"><a href="#3-7" class="headerlink" title="3.7"></a>3.7</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> name = <span class="string">'globa'</span>;</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">A</span>(<span class="params">name</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(name);</span><br><span class="line"> <span class="keyword">this</span>.name = name;</span><br><span class="line"> <span class="keyword">var</span> name = <span class="string">'1'</span>;</span><br><span class="line">}</span><br><span class="line">A.prototype.name = <span class="string">'2'</span>;</span><br><span class="line"><span class="keyword">var</span> a = <span class="keyword">new</span> A(<span class="string">'3'</span>);</span><br><span class="line"><span class="keyword">delete</span> a.name;</span><br><span class="line"><span class="built_in">console</span>.log(a.name);</span><br></pre></td></tr></table></figure>
<h4 id="3-8"><a href="#3-8" class="headerlink" title="3.8"></a>3.8</h4><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fun</span>(<span class="params">n,o</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(o);</span><br><span class="line"> <span class="keyword">return</span> {</span><br><span class="line"> fun: <span class="function"><span class="keyword">function</span>(<span class="params">m</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> fun(m,n);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = fun(<span class="number">0</span>);</span><br><span class="line">a.fun(<span class="number">1</span>);</span><br><span class="line">a.fun(<span class="number">2</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> b = fun(<span class="number">0</span>).fun(<span class="number">1</span>).fun(<span class="number">2</span>).fun(<span class="number">3</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> c = fun(<span class="number">0</span>).fun(<span class="number">1</span>);</span><br><span class="line">c.fun(<span class="number">2</span>).fun(<span class="number">3</span>);</span><br></pre></td></tr></table></figure>
<h3 id="4-_u7EBF_u7A0B"><a href="#4-_u7EBF_u7A0B" class="headerlink" title="4.线程"></a>4.线程</h3><h4 id="4-1"><a href="#4-1" class="headerlink" title="4.1"></a>4.1</h4><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="number">0</span>;</span><br><span class="line"><span class="built_in">console</span>.log(a);</span><br><span class="line"></span><br><span class="line">setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="number">2</span>);</span><br><span class="line">},<span class="number">2000</span>);</span><br><span class="line"></span><br><span class="line">setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="number">1</span>);</span><br><span class="line">},<span class="number">0</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">while</span> (<span class="literal">true</span>) {</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="5-_u5176_u4ED6"><a href="#5-_u5176_u4ED6" class="headerlink" title="5.其他"></a>5.其他</h3><h4 id="5-1"><a href="#5-1" class="headerlink" title="5.1"></a>5.1</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Object</span>.prototype.a = <span class="number">20</span>;</span><br><span class="line"><span class="keyword">var</span> m = <span class="number">1</span>;</span><br><span class="line"><span class="built_in">console</span>.log(m.a);</span><br></pre></td></tr></table></figure>
<h4 id="5-2"><a href="#5-2" class="headerlink" title="5.2"></a>5.2</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Object</span>.prototype.a = <span class="number">20</span>;</span><br><span class="line"><span class="keyword">var</span> v = <span class="number">1.0</span></span><br><span class="line"><span class="built_in">console</span>.log(v.a);</span><br></pre></td></tr></table></figure>
<h4 id="5-3"><a href="#5-3" class="headerlink" title="5.3"></a>5.3</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[,,].length;</span><br></pre></td></tr></table></figure>
<h4 id="5-4"><a href="#5-4" class="headerlink" title="5.4"></a>5.4</h4><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">test</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> </span><br><span class="line"> {</span><br><span class="line"> m: <span class="number">1</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> a = test();</span><br><span class="line"><span class="built_in">console</span>.log(a);</span><br></pre></td></tr></table></figure>
<h4 id="5-5"><a href="#5-5" class="headerlink" title="5.5"></a>5.5</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{<span class="built_in">console</span>.log(<span class="number">1</span>);})()</span><br><span class="line">(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{<span class="built_in">console</span>.log(<span class="number">2</span>);})()</span><br></pre></td></tr></table></figure>
<h4 id="5-6"><a href="#5-6" class="headerlink" title="5.6"></a>5.6</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="number">0.1</span> + <span class="number">0.2</span>;</span><br><span class="line"><span class="built_in">console</span>.log(a);</span><br></pre></td></tr></table></figure>
<h4 id="5-7"><a href="#5-7" class="headerlink" title="5.7"></a>5.7</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log([]+{});</span><br><span class="line"><span class="built_in">console</span>.log({}+{});</span><br><span class="line"><span class="built_in">console</span>.log([]+[]);</span><br><span class="line"><span class="built_in">console</span>.log({}+[]);</span><br></pre></td></tr></table></figure>
<p>未完待续…</p>
<h3 id="u53C2_u8003_u7B54_u6848"><a href="#u53C2_u8003_u7B54_u6848" class="headerlink" title="参考答案"></a>参考答案</h3><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">1.1: 0, 1, 2 1.2: 1, 32, undefined -------------------------------------- 2.1: undefined 2.2: 20 2.3: 1, 50 2.4: 5, 6, 6, "c is not defined" -------------------------------------- 3.1: 3,3,3,3 3.2: undefined, hello undefined 3.3: 20, 20 3.4: 20, 50 3.5: 60 3.6: 20, 50 3.7: 3, 2 3.8: undefined, 0, 0 undefined, 0, 1, 2 undefined, 0, 1, 2 -------------------------------------- 4.1 0,然后浏览器卡死 -------------------------------------- 5.1: 各浏览器输入结果试试 5.2: 各浏览器输入结果试试 5.3: 各浏览器输入结果试试 5.4: undefined 5.5: 报错 5.6: 0.30000000000000004 5.7: 第一个:[object Object] 第二个:[object Object][object Object] 第三个: 第四个:0</span><br></pre></td></tr></table></figure>
<p>答案仅供参考。</p>
]]></content>
<summary type="html">
<![CDATA[<p>近期在学习JS基础的时候,整理了一些相对典型的JS练习题,有助于更好的理解JS相关概念。<br>欢迎在评论区留下你的答案~~我会不定期更新文章内容</p>]]>
</summary>
<category term="javaScript" scheme="http://iwuly.com/tags/javaScript/"/>
<category term="作用域" scheme="http://iwuly.com/tags/%E4%BD%9C%E7%94%A8%E5%9F%9F/"/>
<category term="闭包" scheme="http://iwuly.com/tags/%E9%97%AD%E5%8C%85/"/>
</entry>
<entry>
<title><![CDATA[MongoDB 收藏夹]]></title>
<link href="http://iwuly.com/2016/02/12/%E5%A4%A9%E6%A2%AF%E8%BF%9B%E9%98%B6/mongodb-base/"/>
<id>http://iwuly.com/2016/02/12/天梯进阶/mongodb-base/</id>
<published>2016-02-12T03:18:45.000Z</published>
<updated>2016-06-18T18:26:14.000Z</updated>
<content type="html"><![CDATA[<p>大过年捣鼓了下mongodb的安装与使用,收藏了一些好文,方便以后开发用到可以快速回忆.</p>
<p>链接:<br><a href="https://segmentfault.com/a/1190000002547229#articleHeader4" target="_blank" rel="external">Mac下安装MongoDB 及使用教程</a><br><a href="http://jingyan.baidu.com/article/6fb756ecbfe474241858fb3b.html" target="_blank" rel="external">Mongodb Mac版的安装</a><br><a href="http://www.cnblogs.com/TankMa/archive/2011/06/08/2074947.html" target="_blank" rel="external">MongoDB基本使用</a><br><a href="https://segmentfault.com/a/1190000004057550" target="_blank" rel="external">Node.js操作MongoDB数据库</a><br><a href="https://segmentfault.com/a/1190000003717873" target="_blank" rel="external">MongoDB 常用指令</a><br><a href="http://my.oschina.net/chenhao901007/blog/312367" target="_blank" rel="external">nodejs+express+mongodb简单的例子</a></p>
]]></content>
<summary type="html">
<![CDATA[<p>大过年捣鼓了下mongodb的安装与使用,收藏了一些好文,方便以后开发用到可以快速回忆.</p>
<p>链接:<br><a href="https://segmentfault.com/a/1190000002547229#articleHeader4" target="_]]>
</summary>
<category term="mongodb" scheme="http://iwuly.com/tags/mongodb/"/>
</entry>
<entry>
<title><![CDATA[移动端开发中遇到的那些坑]]></title>
<link href="http://iwuly.com/2016/01/28/%E5%A4%A9%E6%A2%AF%E8%BF%9B%E9%98%B6/%E7%A7%BB%E5%8A%A8%E7%AB%AF%E5%BC%80%E5%8F%91%E4%B8%AD%E9%81%87%E5%88%B0%E7%9A%84%E9%82%A3%E4%BA%9B%E5%9D%91/"/>
<id>http://iwuly.com/2016/01/28/天梯进阶/移动端开发中遇到的那些坑/</id>
<published>2016-01-28T04:02:43.000Z</published>
<updated>2016-06-19T09:30:15.000Z</updated>
<content type="html"><![CDATA[<p>这里会记录我在移动端开发中遇到的一些疑难杂症,不定时更新~~</p>
<p>1.CSS3 修改和去除移动端点击事件出现的背景框<br>解决方法:<br><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><span class="line"><span class="tag">html</span>,</span><br><span class="line"><span class="tag">body</span> <span class="rules">{</span><br><span class="line"> <span class="rule"><span class="attribute">-webkit-tap-highlight-color</span>:<span class="value"> <span class="function">rgba</span>(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>)</span></span>;</span><br><span class="line">}</span></span><br></pre></td></tr></table></figure></p>
<a id="more"></a>
<p>2.css禁止用户选择文本<br><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><span class="line"><span class="tag">html</span>,</span><br><span class="line"><span class="tag">body</span> <span class="rules">{</span><br><span class="line"> <span class="rule"><span class="attribute">-webkit-user-select</span>:<span class="value"> none</span></span>;</span><br><span class="line">}</span></span><br></pre></td></tr></table></figure></p>
<p>3.让网页支持弹性滚动</p>
<p>现在很多for Mobile的HTML5网页内都有快速滚动和回弹的效果,看上去和原生app的效率都有得一拼。<br>要实现这个效果很简单,只需要加一行css代码即可:</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">-webkit-user-<span class="operator"><span class="keyword">select</span>: <span class="keyword">none</span>;</span></span><br></pre></td></tr></table></figure>
<p>4.移动端布局适配方案</p>
<ul>
<li>方案集成:hotcss <ul>
<li>作者: <a href="https://www.imochen.com/" target="_blank" rel="external">imochen</a></li>
<li>项目地址:<a href="https://github.com/imochen/hotcss" target="_blank" rel="external">https://github.com/imochen/hotcss</a></li>
</ul>
</li>
<li>方案集成:flexible <ul>
<li>作者: 某宝</li>
<li>项目地址:<a href="https://github.com/amfe/lib-flexible" target="_blank" rel="external">https://github.com/amfe/lib-flexible</a></li>
</ul>
</li>
</ul>
]]></content>
<summary type="html">
<![CDATA[<p>这里会记录我在移动端开发中遇到的一些疑难杂症,不定时更新~~</p>
<p>1.CSS3 修改和去除移动端点击事件出现的背景框<br>解决方法:<br><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><span class="line"><span class="tag">html</span>,</span><br><span class="line"><span class="tag">body</span> <span class="rules">{</span><br><span class="line"> <span class="rule"><span class="attribute">-webkit-tap-highlight-color</span>:<span class="value"> <span class="function">rgba</span>(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>)</span></span>;</span><br><span class="line">}</span></span><br></pre></td></tr></table></figure></p>]]>
</summary>
<category term="html" scheme="http://iwuly.com/tags/html/"/>
<category term="mobile" scheme="http://iwuly.com/tags/mobile/"/>
</entry>
<entry>
<title><![CDATA[从零天梯:web 实时通信与跨文档通信]]></title>
<link href="http://iwuly.com/2016/01/20/%E4%BB%8E%E9%9B%B6%E5%A4%A9%E6%A2%AF%E7%B3%BB%E5%88%97/web%E5%AE%9E%E6%97%B6%E9%80%9A%E4%BF%A1%E4%B8%8E%E8%B7%A8%E6%96%87%E6%A1%A3%E9%80%9A%E4%BF%A1/"/>
<id>http://iwuly.com/2016/01/20/从零天梯系列/web实时通信与跨文档通信/</id>
<published>2016-01-20T07:20:07.000Z</published>
<updated>2016-11-05T03:52:58.000Z</updated>
<content type="html"><![CDATA[<p> 临近年底越忙碌,前段时间为年会活动开发一个项目,不想到需求越加越多最后写了个webapp,功能类似于微信朋友圈(能发状态、点赞、评论&回复),开发过程中填了不少坑,今天聊一聊消息实时通信那些事,整理了一些学习笔记.</p>
<h4 id="1__u4EC0_u4E48_u662F_u5B9E_u65F6_u901A_u4FE1"><a href="#1__u4EC0_u4E48_u662F_u5B9E_u65F6_u901A_u4FE1" class="headerlink" title="1 什么是实时通信"></a>1 什么是实时通信</h4><p><strong>实时通信:</strong> 在网络连接的时候,需要及时的把服务端上的消息回传到消息。比如在线游戏、微博、电子邮件等。</p>
<a id="more"></a>
<p><strong>实时通信分类:</strong></p>
<ol>
<li>Pull技术,轮询(polling)</li>
<li>Push,反向Ajax(Reverse Ajax)或者叫Comet.<br> 2.1 长轮询(Long Polling)<pre><code>XHR Long Polling (ajax方式),
Jsonp Long Polling (jsonp方式)
</code></pre> 2.2 流推送(Comet Streaming)<pre><code>Multi-part XMLHttpRequest,
Hidden IFrame(Forever IFrames)
</code></pre></li>
<li>WebSocket</li>
</ol>
<hr>
<h3 id="2__u5B9E_u65F6web_u7684_u6F14_u53D8"><a href="#2__u5B9E_u65F6web_u7684_u6F14_u53D8" class="headerlink" title="2 实时web的演变"></a>2 实时web的演变</h3><h4 id="Ajax_u76DB_u884C_u4E4B_u524D"><a href="#Ajax_u76DB_u884C_u4E4B_u524D" class="headerlink" title="Ajax盛行之前"></a>Ajax盛行之前</h4><p><strong>自动刷新整页使页面呈现最新内容:</strong></p>
<ul>
<li>设置meta页面自动刷新机制</li>
</ul>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="title">meta</span> <span class="attribute">http-equiv</span>=<span class="value">“refresh”</span> <span class="attribute">content</span>=<span class="value">“20;url=xxx”</span> /></span></span><br></pre></td></tr></table></figure>
<ul>
<li>定时修改Location.href</li>
</ul>
<p><strong>页面刷新缺点:</strong></p>
<ul>
<li>用户体验极差(每隔一段时间就刷新页面)</li>
<li>流量浪费(整个页面刷新)</li>
</ul>
<h4 id="2-1__u8F6E_u8BE2_uFF08polling_uFF09"><a href="#2-1__u8F6E_u8BE2_uFF08polling_uFF09" class="headerlink" title="2.1 轮询(polling)"></a>2.1 轮询(polling)</h4><p><strong>原理:</strong>客户端定时轮询请求(setInterval),服务器端立刻返回.</p>
<p>示例代码:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">interval = setInterval(polling, <span class="number">1000</span>);<span class="comment">//1000为心跳值,每隔1s请求</span></span><br></pre></td></tr></table></figure></p>
<ul>
<li><strong>优点</strong><br> 简单易用,容易实现<br> <strong>短链接</strong>(简单的ajax请求,可以使get、post,也可以是jsonp)<br> 服务器处理方便<br> 支持跨域(使用jsonp时)<br> 所有浏览器都支持<br> 每次请求,立刻返回</li>
<li><strong>缺点</strong><br> 可能会出现延迟(每隔几秒模拟,并不能保证是实时消息)<br> 浪费流量(并不知道服务器有木有最新数据,要不断向服务器请求)<br> 建立大量链接,(用户数越多与服务器连接的请求也越多,服务器并发量大,处理变慢)</li>
</ul>
<p>微博未读微博数和未读消息(评论,@)就是用polling实现的。<br>应用场景:对实时性要求不高的应用,如新微博提示,评论提示,回复提示等。</p>
<h4 id="2-2_Comet_uFF1A_u57FA_u4E8EHTTP_u957F_u8FDE_u63A5_u7684_u201C_u670D_u52A1_u5668_u63A8_u201D_u6280_u672F"><a href="#2-2_Comet_uFF1A_u57FA_u4E8EHTTP_u957F_u8FDE_u63A5_u7684_u201C_u670D_u52A1_u5668_u63A8_u201D_u6280_u672F" class="headerlink" title="2.2 Comet:基于HTTP长连接的“服务器推”技术"></a>2.2 Comet:基于HTTP长连接的“服务器推”技术</h4><p>(也有人叫做反向ajax)</p>
<p><strong>原理:</strong>客户端发起连接,服务器端会阻塞请求(服务器端hold网络连接)直到有数据传递或超时(心跳时间)才返回.</p>
<p>实现方式主要有2种:<strong>长轮询(Long Polling)</strong>和 <strong>流推送(Comet Streaming)</strong></p>
<p>两种实现方式:</p>
<p><strong>长轮询(long polling)</strong></p>
<p><strong>1 XHR Long Polling (ajax方式)</strong></p>
<ul>
<li>原理:客户端发起一个XHR ajax request,服务器端会阻塞请求直到有数据传递或超时才返回<br>客户端收到response之后马上再发起一个新的request,周而复始。(当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所有的信息取回。)</li>
</ul>
<p><strong>2 Jsonp Long Polling (jsonp方式)</strong></p>
<ul>
<li>原理:跟XHR Long Polling类似,只是结合long polling和jsonp,用来支持跨域(cross-domain)请求。</li>
</ul>
<p>连接需要后端靠hold住(让进程休眠),对服务器端的架构考验比较大</p>
<p><strong>优点:</strong>减少轮询,低延迟, 各大浏览器均支持;<br><strong>缺点:</strong>服务器需要hold住大量connection,ajax方式不支持跨域.</p>
<p>ps:在这种长轮询方式下,客户端是在 XMLHttpRequest 的 readystate 为 4(即数据传输结束)时调用回调函数,进行信息处理。当 readystate 为 4 时,数据传输结束,连接已经关闭。Mozilla Firefox 提供了对 Streaming AJAX 的支持,<br>即 readystate 为 3 时(数据仍在传输中),客户端可以读取数据,从而无须关闭连接,就能读取处理服务器端返回的信息.IE 在 readystate 为 3 时,不能读取服务器返回的数据,目前 IE 不支持基于 Streaming AJAX。</p>
<p>微博私信提示就是用Jsonp Long Polling实现。<br>Long Polling的应用场景:对实时性要求较高和浏览器覆盖面广的应用,如私信等一些简单即时聊天应用。</p>
<p><strong>流推送(comet streaming )</strong></p>
<ul>
<li>Multi-part XMLHttpRequest</li>
<li>Hidden IFrame(Forever IFrames)</li>
</ul>
<p><strong>1 Multi-part XMLHttpRequest</strong></p>
<p><strong>优点:</strong>客户端一次连接,服务器数据可多次推送。<br><strong>缺点:</strong>并非所有的浏览器都支持 multi-part 标志。</p>
<p>-----对他不是很了解,欢迎在大家在评论区补充------</p>
<p><strong>2 Hidden IFrame(Forever IFrames)</strong><br>建立一个隐藏的iframe,利用iframe建立长连接。<br>(iframe src 属性设为对一个长连接的请求,服务器端就能源源不断地往客户端输入数据。)</p>
<p><strong>优点:</strong>客户端一次连接,服务器数据可多次推送。几乎所有支持iframe 的浏览器上都可用。<br><strong>缺点:</strong>不可跨域,错误处理可控性不强 </p>
<p>流推送的应用场景:实时监控系统,即时聊天</p>
<hr>
<h4 id="http_u5B9E_u65F6_u901A_u4FE1_u7F3A_u9677"><a href="#http_u5B9E_u65F6_u901A_u4FE1_u7F3A_u9677" class="headerlink" title="http实时通信缺陷"></a>http实时通信缺陷</h4><p>http通信特点:</p>
<ul>
<li>无状态连接(需要对每个客户端的连接维持)</li>
<li>单向通信</li>
<li>每个请求都包括header信息(cookie, Cache-Control,content-type, Expires)</li>
</ul>
<ul>
<li>服务器被迫为每个客户端使用一些不同的底层TCP连接: </li>
<li>一个用于发送信息到客户端和一个新的用于每个传入消息。</li>
<li>线路层协议有较高的开销,因为每个客户端-服务器消息都有一个HTTP头信息。</li>
<li>客户端脚本被迫维护一个传出的连接到传入的连接的映射来跟踪回复。</li>
</ul>
<h3 id="3_websocket_u4ECB_u7ECD"><a href="#3_websocket_u4ECB_u7ECD" class="headerlink" title="3 websocket介绍"></a>3 websocket介绍</h3><h4 id="3-1_websocket_u7684_u8BDE_u751F"><a href="#3-1_websocket_u7684_u8BDE_u751F" class="headerlink" title="3.1 websocket的诞生"></a>3.1 websocket的诞生</h4><p>定义了一个浏览器和服务器之间的全双工的单一的socket连接取代现有的HTTP作为传输层的双向通信技术W3C将其纳入规范,写入HTML5版本</p>
<h4 id="3-2_websocket_u63A5_u53E3"><a href="#3-2_websocket_u63A5_u53E3" class="headerlink" title="3.2 websocket接口"></a>3.2 websocket接口</h4><p>onopen 在WS客户端和WS服务器建立连接成功后调用<br>onmessage 在WS服务器给WS客户端发送数据时调用<br>onerror 如果连接失败,发送、接收数据失败或者处理数据出现错误,则会被调用<br>onclose 在WS客户端接收到WS服务器关闭时进行调用</p>
<h4 id="3-3_websocket__u5B9E_u4F8B"><a href="#3-3_websocket__u5B9E_u4F8B" class="headerlink" title="3.3 websocket 实例"></a>3.3 websocket 实例</h4><p><strong>浏览器端实现</strong></p>
<ol>
<li>Websocket 实例化</li>
<li>定义open\message\cloes\error事件</li>
</ol>
<p><strong>服务端(nodejs)实现</strong></p>
<ol>
<li>构建websocket服务器</li>
<li>处理connection事件,实现与客户端通信</li>
</ol>
<p><strong>思考:如何做技术选型?</strong></p>
<hr>
<h3 id="4__u8DE8_u6587_u6863_u901A_u4FE1_u5B9E_u73B0_u65B9_u5F0F"><a href="#4__u8DE8_u6587_u6863_u901A_u4FE1_u5B9E_u73B0_u65B9_u5F0F" class="headerlink" title="4 跨文档通信实现方式"></a>4 跨文档通信实现方式</h3><h4 id="4-1_Window_u547D_u540D_u7A7A_u95F4_u8FDB_u884C_u4F20_u9012_uFF1A"><a href="#4-1_Window_u547D_u540D_u7A7A_u95F4_u8FDB_u884C_u4F20_u9012_uFF1A" class="headerlink" title="4.1 Window命名空间进行传递:"></a>4.1 Window命名空间进行传递:</h4><p>window.name = “hello”;</p>
<p>优点:简单<br>缺点:</p>
<ul>
<li>无法跨域</li>
<li>无法实现不同窗体之间的通信</li>
</ul>
<p>示例代码<a href="http://iwuly.com/snippets/?searchId=003">window.name实现的跨域数据传输</a></p>
<h4 id="4-2_postmessage"><a href="#4-2_postmessage" class="headerlink" title="4.2 postmessage"></a>4.2 postmessage</h4><p>信差大使——postmessage: 监听message事件,通过event对象获取消息</p>
<p>data 包含任意字符串数据,由原始脚本发送<br>origin 一个字符串,包含原始文档的方案、域名以及端口(如:<a href="http://domain.example:80" target="_blank" rel="external">http://domain.example:80</a>)<br>lastEventId 一个字符串,包含了当前的消息事件的唯一标识符。<br>source 原始文件的窗口的引用。更确切地说,它是一个WindowProxy对象。<br>ports 一个数组,包含任何MessagePort对象发送消息。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> messageHandle = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> alert(<span class="number">1</span>);</span><br><span class="line">} </span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(<span class="built_in">window</span>.addEventListener) {</span><br><span class="line"> <span class="built_in">window</span>.addEventListener(<span class="string">'message'</span>, messageHandle, <span class="literal">false</span>);</span><br><span class="line">}<span class="keyword">else</span> <span class="keyword">if</span> (<span class="built_in">window</span>.attachEvent) {<span class="comment">//IE的写法</span></span><br><span class="line"> <span class="built_in">window</span>.attachEvent(<span class="string">'onmessage'</span>,messageHandle);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">window</span>.parent.frames[<span class="number">1</span>].postMessage(message,<span class="string">'*'</span>);</span><br></pre></td></tr></table></figure>
<p>示例代码请<a href="http://iwuly.com/snippets/?searchId=004">postMessage跨文档实现方案</a></p>
<hr>
<h3 id="5__u53C2_u8003_u6587_u6863"><a href="#5__u53C2_u8003_u6587_u6863" class="headerlink" title="5 参考文档"></a>5 参考文档</h3><p><a href="http://www.iqiyi.com/w_19rs59narl.html?t=1454829077177#vfrm=8-8-0-3" target="_blank" rel="external">HTML5即时通讯</a><br><a href="http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html#m2" target="_blank" rel="external">JavaScript跨域总结与解决办法</a><br><a href="http://blog.csdn.net/z69183787/article/details/19191385" target="_blank" rel="external">JSONP原理优缺点</a><br><a href="http://blog.phpha.com/backup/archives/1668.html" target="_blank" rel="external">基于WEB的实时通信方案</a><br><a href="http://blog.csdn.net/bao19901210/article/details/21458001" target="_blank" rel="external">window.name实现的跨域数据传输</a><br><a href="http://www.cnblogs.com/dolphinX/p/3464056.html" target="_blank" rel="external">html5 postMessage解决跨域、跨窗口消息传递</a></p>
]]></content>
<summary type="html">
<![CDATA[<p> 临近年底越忙碌,前段时间为年会活动开发一个项目,不想到需求越加越多最后写了个webapp,功能类似于微信朋友圈(能发状态、点赞、评论&回复),开发过程中填了不少坑,今天聊一聊消息实时通信那些事,整理了一些学习笔记.</p>
<h4 id="1__u4EC0_u4E48_u662F_u5B9E_u65F6_u901A_u4FE1"><a href="#1__u4EC0_u4E48_u662F_u5B9E_u65F6_u901A_u4FE1" class="headerlink" title="1 什么是实时通信"></a>1 什么是实时通信</h4><p><strong>实时通信:</strong> 在网络连接的时候,需要及时的把服务端上的消息回传到消息。比如在线游戏、微博、电子邮件等。</p>]]>
</summary>
<category term="web 实时通信" scheme="http://iwuly.com/tags/web-%E5%AE%9E%E6%97%B6%E9%80%9A%E4%BF%A1/"/>
<category term="跨域" scheme="http://iwuly.com/tags/%E8%B7%A8%E5%9F%9F/"/>
</entry>
<entry>
<title><![CDATA[从零天梯:设计模式之观察者模式]]></title>
<link href="http://iwuly.com/2016/01/03/%E5%A4%A9%E6%A2%AF%E8%BF%9B%E9%98%B6/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F/"/>
<id>http://iwuly.com/2016/01/03/天梯进阶/设计模式之观察者模式/</id>
<published>2016-01-03T15:27:09.000Z</published>
<updated>2016-10-08T15:22:39.000Z</updated>
<content type="html"><![CDATA[<p>学习观察者模式的时候发现自己有很多不懂,主要是平时项目没有用到,所以比较陌生。工作之余抓着间隙虚心向同事讨教了几招,整理了一下自己的近期学习笔记。如有纰漏,欢迎留言&评论~~</p>
<a id="more"></a>
<h4 id="1__u4E1A_u52A1_u573A_u666F"><a href="#1__u4E1A_u52A1_u573A_u666F" class="headerlink" title="1 业务场景"></a>1 业务场景</h4><p> 了解观察者模式,咱们可以先看看这段代码。<br> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$(<span class="string">'#btn'</span>).on(<span class="string">'click'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="comment">//回调函数</span></span><br><span class="line">});</span><br></pre></td></tr></table></figure></p>
<p> 使用jQuery的同学对这段代码都很熟悉吧~~<br> 监听#btn的click事件并给予回调。很早的时候,业务逻辑我是直接写在回调函数里的。然而业务变复杂后,<br> 这种写法的短板也就出来了,<strong>程序结构不清晰,耦合度高,代码重用性低</strong>等等。后来我尝试了这样:<br> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">A</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="comment">//业务逻辑</span></span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">B</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="comment">//业务逻辑</span></span><br><span class="line">}</span><br><span class="line">$(<span class="string">'#btn1'</span>).on(<span class="string">'click'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> A();</span><br><span class="line"> B();</span><br><span class="line"> ...</span><br><span class="line">});</span><br><span class="line">$(<span class="string">'#btn2'</span>).on(<span class="string">'click'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> A();</span><br><span class="line"> B();</span><br><span class="line"> ...</span><br><span class="line">});</span><br></pre></td></tr></table></figure></p>
<p> 剥离业务逻辑到外部函数,然后在回调函数里调用外部函数。同时,剥离出来的代码其他地方也能调用。<br> 但是这样还不是最完美的,当类似 function A(), function B()的公共函数变得很多时,程序就变得很难管理,<br> 所以我们就需要一个<strong>事件管理中心(观察者模式)</strong>对这些方法进行<strong>统一管理(分类、订阅、发布、销毁)</strong>。</p>
<h4 id="2__u89C2_u5BDF_u8005_u6A21_u5F0F_u6982_u8981"><a href="#2__u89C2_u5BDF_u8005_u6A21_u5F0F_u6982_u8981" class="headerlink" title="2 观察者模式概要"></a>2 观察者模式概要</h4><h5 id="2-1__u4EC0_u4E48_u662F_u89C2_u5BDF_u8005_u6A21_u5F0F"><a href="#2-1__u4EC0_u4E48_u662F_u89C2_u5BDF_u8005_u6A21_u5F0F" class="headerlink" title="2.1 什么是观察者模式"></a>2.1 什么是观察者模式</h5><p>观察者模式又叫<strong>发布订阅模式(Publish/Subscribe)</strong>,它定义了一种一对多的关系,让多个观察者对象同时监听同一主题对象,这个主题对象的状态发生变化时,就会通知所有的观察者对象,使得它们能够自动更新自己。</p>
<h5 id="2-2__u89C2_u5BDF_u8005_u6A21_u5F0F_u4F5C_u7528_u548C_u6CE8_u610F_u4E8B_u9879"><a href="#2-2__u89C2_u5BDF_u8005_u6A21_u5F0F_u4F5C_u7528_u548C_u6CE8_u610F_u4E8B_u9879" class="headerlink" title="2.2 观察者模式作用和注意事项"></a>2.2 观察者模式作用和注意事项</h5><ul>
<li><p>模式作用:</p>
<ul>
<li>支持简单的广播通信,自动通知所有已经订阅过的对象。(<strong>全局通知</strong>)</li>
<li>页面载入后目标对象很容易与观察者存在一种动态关联,增加了灵活性。(<strong>等待被调用</strong>)</li>
<li>目标对象与观察者之间的抽象耦合关系能够单独扩展以及重用。(<strong>模块化</strong>)</li>
</ul>
</li>
<li><p>注意事项:</p>
<ul>
<li>触发事件之前需预选订阅事件。</li>
</ul>
</li>
</ul>
<h4 id="3__u89C2_u5BDF_u8005_u6A21_u5F0F_u6838_u5FC3_u5B9E_u73B0"><a href="#3__u89C2_u5BDF_u8005_u6A21_u5F0F_u6838_u5FC3_u5B9E_u73B0" class="headerlink" title="3 观察者模式核心实现"></a>3 观察者模式核心实现</h4><h5 id="3-1__u5B9E_u73B0_u601D_u8DEF"><a href="#3-1__u5B9E_u73B0_u601D_u8DEF" class="headerlink" title="3.1 实现思路"></a>3.1 实现思路</h5><p>举个生活中的例子,观察者模式有点类似于报纸订阅中心,用户如果需要阅读报纸,就需要预先要在订阅中心订阅报纸,中心会有一份名单,记录某某某订阅了报纸,然后工作人员会按照名单把报纸投递到相应的用户手上.如果用户不再需要阅读,则可以在中心申请取消订阅.</p>
<p>那么我们可以整理出观察者模式与例子中的联系:</p>
<ul>
<li>订阅名单——<strong>存取订阅关系的数据(Data)</strong></li>
<li>用户向中心订阅报纸——<strong>订阅事件(sub)</strong></li>
<li>投递报纸——<strong>发布事件(pub)</strong></li>
<li>用户申请取消订阅报纸——<strong>取消订阅(unsub)</strong></li>
</ul>
<p>如果用代码展示他们之间的关系,可以用一个对象以key-value的形式保存关系。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">eventList = {</span><br><span class="line"> <span class="string">'事件A'</span>: [functionA, functionB]</span><br><span class="line">, <span class="string">'事件B'</span>: [functionC, functionD]</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p> 这样看来就很好理解了:</p>
<p> 订阅事件(sub):生成一个键制度,key存放事件名,value存放函数的引用.<br> 发布事件(pub):查找对应的key值,并将key对应的value里function都执行一遍<br> 取消订阅(unsub):去掉key值及其对应的value值。</p>
<h5 id="3-2__u5B9E_u73B0_u4EE3_u7801"><a href="#3-2__u5B9E_u73B0_u4EE3_u7801" class="headerlink" title="3.2 实现代码"></a>3.2 实现代码</h5><p>构建一个事件管理器对象:<br><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></pre></td><td class="code"><pre><span class="line">(<span class="function"><span class="keyword">function</span>(<span class="params">$, window, undefined</span>) </span>{</span><br><span class="line"> <span class="comment">//构建一个事件管理器对象</span></span><br><span class="line"> <span class="built_in">window</span>.EventCenter = {</span><br><span class="line"> o: $({}), <span class="comment">//创建一个空jq对象,用来存储订阅关系数据</span></span><br><span class="line"> sub: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{ <span class="comment">//订阅事件</span></span><br><span class="line"> <span class="keyword">var</span> self = <span class="keyword">this</span>;</span><br><span class="line"> <span class="comment">//借助on函数绑定自定义事件</span></span><br><span class="line"> self.o.on.apply(self.o, <span class="built_in">arguments</span>);</span><br><span class="line"> },</span><br><span class="line"> pub: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{ <span class="comment">//发布事件</span></span><br><span class="line"> <span class="keyword">var</span> self = <span class="keyword">this</span>;</span><br><span class="line"> <span class="comment">//借助trigger函数模拟触发</span></span><br><span class="line"> self.o.trigger.apply(self.o, <span class="built_in">arguments</span>);</span><br><span class="line"> },</span><br><span class="line"> unsub: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{ <span class="comment">//取消订阅事件</span></span><br><span class="line"> <span class="keyword">var</span> self = <span class="keyword">this</span>;</span><br><span class="line"> <span class="comment">//借助off函数解除事件绑定</span></span><br><span class="line"> self.o.off.apply(self.o, <span class="built_in">arguments</span>);</span><br><span class="line"> }</span><br><span class="line"> };</span><br><span class="line">})(jQuery, <span class="built_in">window</span>);</span><br></pre></td></tr></table></figure></p>
<p>使用方法:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//使用方法</span></span><br><span class="line"><span class="comment">//订阅事件,'/test/ls'为事件名称(事件频道)</span></span><br><span class="line">EventCenter.sub(<span class="string">'/test/ls'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> event = <span class="built_in">arguments</span>[<span class="number">0</span>];</span><br><span class="line"> <span class="comment">//事件对象</span></span><br><span class="line"> <span class="built_in">console</span>.log(event);</span><br><span class="line"> <span class="comment">//函数传入参数</span></span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">arguments</span>);</span><br><span class="line">});</span><br><span class="line"><span class="comment">//点击发布事件按钮,触发事先订阅的事件</span></span><br><span class="line">$(<span class="string">'#btn01'</span>).on(<span class="string">'click'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> argument = [<span class="string">'param01'</span>,<span class="string">'param02'</span>];</span><br><span class="line"> EventCenter.pub(<span class="string">'/test/ls'</span>, argument);</span><br><span class="line">});</span><br><span class="line"></span><br><span class="line"><span class="comment">//点击取消订阅按钮(事件取消后,点击发布事件按钮失效)</span></span><br><span class="line">$(<span class="string">'#btn02'</span>).on(<span class="string">'click'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> EventCenter.unsub(<span class="string">'/test/ls'</span>);</span><br><span class="line">});</span><br></pre></td></tr></table></figure></p>
<p>查看完整代码请<a href="http://iwuly.com/snippets/?searchId=002">猛戳这里</a>。</p>
<h4 id="4__u53C2_u8003_u8D44_u6599"><a href="#4__u53C2_u8003_u8D44_u6599" class="headerlink" title="4 参考资料"></a>4 参考资料</h4><p><a href="http://blog.csdn.net/tjvictor/article/details/5223309" target="_blank" rel="external">设计模式—订阅发布模式(Subscribe/Publish)</a><br><a href="http://baike.baidu.com/link?url=lWPrFN9sAPxLzfdn8eDsHMIIi8REuLlNi2jnPiH6Qvh3ufLexs0LTbmUUcglEzd3AofXovv6EHSOeQFtRT35_a" target="_blank" rel="external">百度百科-观察者模式</a><br><a href="http://www.cnblogs.com/li-peng/archive/2013/02/04/2892116.html" target="_blank" rel="external">设计模式:观察者模式</a><br><a href="http://shihuacivis.github.io/2015/09/10/20150910_subPub/" target="_blank" rel="external">Js实现基于发布/订阅机制的事件管理器(观察者模式)</a></p>
]]></content>
<summary type="html">
<![CDATA[<p>学习观察者模式的时候发现自己有很多不懂,主要是平时项目没有用到,所以比较陌生。工作之余抓着间隙虚心向同事讨教了几招,整理了一下自己的近期学习笔记。如有纰漏,欢迎留言&评论~~</p>]]>
</summary>
<category term="观察者模式" scheme="http://iwuly.com/tags/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F/"/>
<category term="设计模式" scheme="http://iwuly.com/tags/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"/>
</entry>
<entry>
<title><![CDATA[平凡之路—写在2015年的尾巴]]></title>
<link href="http://iwuly.com/2015/12/31/%E7%94%9F%E6%B4%BB%E7%82%B9%E6%BB%B4/%E5%86%99%E5%9C%A82015%E5%B9%B4%E7%9A%84%E5%B0%BE%E5%B7%B4/"/>
<id>http://iwuly.com/2015/12/31/生活点滴/写在2015年的尾巴/</id>
<published>2015-12-31T15:59:59.000Z</published>
<updated>2016-10-07T16:18:33.000Z</updated>
<content type="html"><![CDATA[<p> 今天是2015年12月31日,晴。</p>
<p>早在几月前,我便提醒自己,不论文笔如何,总要记录点什么,颇有几分励志的味道在里面。 </p>
<p>2015年,是繁忙的一年。年初确定了自己的职业方向,随后在老板的体谅下,我结束了实习之旅。回到学校,开始为弄毕业设计忙碌,中间整理了过去实习的经验,还看了不少有关前端的经典书籍。终于在6月份毕业了,从此我过上了跟大部分人不大一样的人生。白天上班,晚上看书、写demo、折腾点业余东西。技术上虽然比年初进步了不少,但我知道自己还差的很远呢!繁忙之后,回首看看这一年的路,终究还是一条,<strong>平凡之路</strong>。</p>
<a id="more"></a>
<h3 id="u5173_u4E8E_u6280_u672F"><a href="#u5173_u4E8E_u6280_u672F" class="headerlink" title="关于技术"></a>关于技术</h3><p>参加完D2前端大会,发现今年的主题基本围绕着react和node。前端工程化、webapp经常能听到大家的一些交流。自己平时也就私下捣鼓,瞎折腾。之前用Angular参与过几个大型项目,ui-router,自定义指令,国际化翻译,都玩过。不过现在公司的项目主要是基于jQuery,主要负责web页面开发,app内webview页面的活动开发。入职半年,把之前单一的可重复性低的活动折腾成了可后台配置,前端模版和控件可自由搭配,可重复性较高的活动接入系统。由于初期经验不足考虑不全面,导致期间架构一直在迭代,更新了五六个小版本,一个大版本。很多东西在实践中摸索,在摸索中找方案,体会到了做产品的不容易之处。真心是做了才知道的感觉,光说不练绝对体会不到。</p>
<h3 id="u535A_u5BA2_u4EE5_u53CAgithub"><a href="#u535A_u5BA2_u4EE5_u53CAgithub" class="headerlink" title="博客以及github"></a>博客以及github</h3><p>说到博客也挺惭愧。其实在学生时代,我就有写博客的想法。可惜坚持不够,那时候没有把这想法落地。网上能写博客的论坛有很多,相比之下我更喜欢自己折腾,从<strong>wordpress</strong>到<strong>hexo</strong>,中间还玩过阿里云服务器(博客最后放在github上)。通过这个博客,我接触了一些同行,他们身上近乎透着同一种特质:喜欢技术,爱折腾,明白自己想要什么不想要什么。他们能看到我看不到的东西,知道很多以前我想都没想过的知识,跟这群人的接触,能让自己看到不足,及时调整状态。我感谢每个帮助过我的人。<br>说到github就更丢脸了。本来计划今年好好玩github的。没想到把账号给丢了 = =# 心塞塞。。无奈只好重新注册一个。虽然自己的技术还不咋地,不怎么拿的出手,但是好歹迈出了第一步, 跟着前端群里的大牛折腾一些小项目。不过今年要做的事情还有很多,能把博客坚持写好就不错了。</p>
<h3 id="u8BFB_u4E66"><a href="#u8BFB_u4E66" class="headerlink" title="读书"></a>读书</h3><p>2015年买了很多书,但是能坚持通读一遍的却很少。上班之后常常感觉时间妥妥的不够,所以晚上是我学习的时间。</p>
<ul>
<li><p><em>《javascript高级程序设计》</em><br>- 第三版读完了。持续时间太长,基本上是边读边忘。今年没有好目标的话再读一遍。</p>
</li>
<li><p><em>《HTML5+CSS3从入门到精通》</em><br>- 从头到尾看了一遍,把自己破碎的知识片段拼成了一块。可惜的是,书中并没有介绍websocket、文件api等相关内容</p>
</li>
<li><p><em>《超实用的css代码段》《超实用的javascript代码段》《超实用的jQuery代码段》</em><br>- 实用性书籍,一口气买了这一系列的全部,里面有很多奇技淫巧,如果能把这里面的demo撸完,估计能让技术提升不只一个台阶。目前只是视为自己的代码仓库,项目需要的时候才会想起,从中了解某个功能的实现原理。</p>
</li>
<li><p><em>《jQuery基础教程》《锋利的jquery》</em><br>- 公司项目需要用到jQuery,硬着头皮看完,偶尔还会翻翻查查某些api的用法。</p>
</li>
<li><p><em>《精通AngularJs》《AngularJs权威教程》</em><br>- 年前买的。如果入门建议还是买后者吧,前者感觉不大实用,很多东西不能落地项目。不过两者更多的是介绍用法,对AngularJS内部原理介绍的比较少。当我知道vue后,再也没鸟过这两本书。。</p>
</li>
<li><p><em>《你所不知道的javascript 上卷》</em><br>- 比较薄的一本,高程看不进去了,就会看这本。</p>
</li>
<li><p>《Web前端黑客技术揭秘》<br>- pdf版,最近正在读的一本。</p>
</li>
<li><p>《JavaScript框架设计》<br>- 额…技术还没到这个火候,感觉像在看一本天书。</p>
</li>
</ul>
<p>看的比较杂,2016年计划按照技术难度<strong>循序渐进</strong>的阅读。已有的书籍有时间的话再读几遍。未来买书可能更理智些,纸质太厚重,也许会考虑一些电子书。技术上计划偏向于学习了解原理或底层,以及原生的一些知识。</p>
<h3 id="u6280_u672F_u4EA4_u6D41"><a href="#u6280_u672F_u4EA4_u6D41" class="headerlink" title="技术交流"></a>技术交流</h3><p>年前加入了一个前端交流群,那时候群里每周五进行视频直播分享,学到了不少东西,在群里算是活跃了一年了。在平时的交流中学到了点点滴滴数不清的知识。刚开始各种提问学习,后来做一些项目,技术经验累积了,渐渐能为群贡献自己的力量。回首过去,自己的成长,离不开QQ群。感谢<strong>89hi(130977811)</strong>的小伙伴!<br>还有一个就是,<strong>javascript后花园(116366053)</strong>,高级前端群,我已经在群里潜伏快一年了,经常能看到业界大牛们之间的交流,对自己的技术提高以及未来方向的把控很有帮助。</p>
<h3 id="u751F_u6D3B"><a href="#u751F_u6D3B" class="headerlink" title="生活"></a>生活</h3><p>我是个完全不懂生活的呆傻理工男,但今年开始也要学着调剂生活了。一味的埋头代码,或者是看电影打游戏,或许不是生活的全部。自己很少会主动想起买衣服,但唯独对电子设备情有独钟,竞技鼠标,单反,甚至6s , mac pro。都是攒钱买的,拿到手的时候仿佛拿到了一件趁手的兵器。今年目标就是<strong>存钱!存钱!存钱!(重要的事情要说三遍)</strong><br>年前还报了驾校学车,天天在驾校装孙子,也是一部分时间开销。当时问驾校能不能在毕业前考出驾照,回复行,于是就报名了。到毕业时才到科目二,上了班再也没去驾校过。。。估计教练也不记得我这个人了吧。。。<br><strong>生活像代码一样,就这么几行。。。</strong></p>
<h3 id="u60F3_u6CD5_u4EE5_u53CA_u672A_u6765"><a href="#u60F3_u6CD5_u4EE5_u53CA_u672A_u6765" class="headerlink" title="想法以及未来"></a>想法以及未来</h3><p>曾经有人不理解,说我工作狂,拿出这么多时间学这个,最后将来还有没有用,我们程序员不就是这样的么?知识需要更新。尽管他时间可能很短,等到新的技术出来以后,老的技术也将完成他的历史使命。但是他需要一个接力的过程。我在想,不管从事什么职业,要有一种甘于寂寞的精神准备。尽管我现在什还不足强大,但是我非常感谢母校,对我的培养,以及我的老师和我的同学们,一直陪伴着我,所以,我要努力,但是<strong>不要着急,凡事都有应该有过程</strong>。不光是我,前端圈里,有很多群,有很多像我一样每天在学习的人。因为他们跟我有同样的年龄的,一样的想法,对于未来迷茫或呈现的那种尴尬。每一个人怎么会是一样的呢,是你没看见他们背后努力的样子吧。不是所有人都是主角,大部分人一辈子可能要甘于寂寞,或甘于平庸,但是并不要打击他们的努力。曾经我也迷茫过,最后在知乎上找到了答案[<a href="https://www.zhihu.com/question/38696079" target="_blank" rel="external">如何避免工作两年重复一年工作经验?</a>]。引用里面的精彩回复:</p>
<blockquote>
<p>“看到有些刚毕业的同学,每天都大把大把的时间投入深入研究一些新技术新概念,这样的人能不牛逼么?你必须要尊敬他,因为他未来肯定比你牛逼。”</p>
</blockquote>
<h3 id="u6700_u540E"><a href="#u6700_u540E" class="headerlink" title="最后"></a>最后</h3><p>2015年挺精彩的,很多方面,都有了一些质的改变。其实我是个成长特别慢的人,能够做到这些改变,自己也算是很满意啦。如果满分💯,我能给自己<strong>60</strong>分。希望接下来的2016,能够收获更多。</p>
<p>祝福每个人。</p>
]]></content>
<summary type="html">
<![CDATA[<p> 今天是2015年12月31日,晴。</p>
<p>早在几月前,我便提醒自己,不论文笔如何,总要记录点什么,颇有几分励志的味道在里面。 </p>
<p>2015年,是繁忙的一年。年初确定了自己的职业方向,随后在老板的体谅下,我结束了实习之旅。回到学校,开始为弄毕业设计忙碌,中间整理了过去实习的经验,还看了不少有关前端的经典书籍。终于在6月份毕业了,从此我过上了跟大部分人不大一样的人生。白天上班,晚上看书、写demo、折腾点业余东西。技术上虽然比年初进步了不少,但我知道自己还差的很远呢!繁忙之后,回首看看这一年的路,终究还是一条,<strong>平凡之路</strong>。</p>]]>
</summary>
<category term="杂谈" scheme="http://iwuly.com/tags/%E6%9D%82%E8%B0%88/"/>
<category term="畅想" scheme="http://iwuly.com/tags/%E7%95%85%E6%83%B3/"/>
</entry>
<entry>
<title><![CDATA[从零天梯:Ajax浅析]]></title>
<link href="http://iwuly.com/2015/02/01/%E4%BB%8E%E9%9B%B6%E5%A4%A9%E6%A2%AF%E7%B3%BB%E5%88%97/Ajax%E6%B5%85%E6%9E%90/"/>
<id>http://iwuly.com/2015/02/01/从零天梯系列/Ajax浅析/</id>
<published>2015-02-01T13:05:54.000Z</published>
<updated>2016-10-18T15:34:43.000Z</updated>
<content type="html"><![CDATA[<h3 id="u524D_u8A00"><a href="#u524D_u8A00" class="headerlink" title="前言"></a>前言</h3><p>前段时间群里做知识分享,<a href="http://www.cnblogs.com/lvdabao/" target="_blank" rel="external">大豹</a>老师分享了他对Ajax的一些心得体会,当时听的比较入迷,整理了一些笔记,希望对大家有帮助。</p>
<h3 id="u77E5_u8BC6_u76EE_u5F55_u7ED3_u6784"><a href="#u77E5_u8BC6_u76EE_u5F55_u7ED3_u6784" class="headerlink" title="知识目录结构"></a>知识目录结构</h3><ul>
<li>Ajax 基础知识</li>
<li>jQuery中Ajax的相关用法</li>
<li>jQuery中Ajax全局设置和全局事件</li>
<li>表单数据序列化</li>
<li>实际应用中的注意事项</li>
<li>知识扩展</li>
<li>参考资料<a id="more"></a>
</li>
</ul>
<h3 id="1_Ajax__u57FA_u7840_u77E5_u8BC6"><a href="#1_Ajax__u57FA_u7840_u77E5_u8BC6" class="headerlink" title="1 Ajax 基础知识"></a>1 Ajax 基础知识</h3><h4 id="1-1Ajax_u662F_u4EC0_u4E48"><a href="#1-1Ajax_u662F_u4EC0_u4E48" class="headerlink" title="1.1Ajax是什么"></a>1.1Ajax是什么</h4><p>Ajax的全称是Asyncronous Javascript And XML(异步传输JavaScript+XML)</p>
<ul>
<li>直白地说,就是没用Ajax的页面,你点一个按钮就要刷新一下页面,尽管新页面上只有一行和当前页面不一样,但还是要无聊地等待页面刷新。</li>
<li>用了Ajax之后再点击,然后页面上的一行就变化了,页面本身不用刷新。(简称页面无刷新数据交互)</li>
<li>Ajax只是一种技术,不是某种具体的东西。不同的浏览器有自己的实现的Ajax的组件。</li>
<li>XML只是一种数据格式,在这里并不重要,现在大部分人用JSON格式代替XML,原因是JSON更加简洁,解析速度也更快。</li>
</ul>
<p><strong>总结: 只要是JS调用异步通讯组件并使用格式化的数据来更新web页面上的内容或操作过程,那么我们用的方法就可算是Ajax。</strong></p>
<h4 id="1-2__u540C_u6B65_u548C_u5F02_u6B65"><a href="#1-2__u540C_u6B65_u548C_u5F02_u6B65" class="headerlink" title="1.2 同步和异步"></a>1.2 同步和异步</h4><p>javascript是单线程的,代码始终自上往下依次执行。</p>
<p>可以异步执行的代码:Ajax、setTimeout、setInterval。</p>
<h4 id="1-3__u5F02_u6B65_u8BF7_u6C42_u6709_u4EC0_u4E48_u7528_u9014_uFF1F"><a href="#1-3__u5F02_u6B65_u8BF7_u6C42_u6709_u4EC0_u4E48_u7528_u9014_uFF1F" class="headerlink" title="1.3 异步请求有什么用途?"></a>1.3 异步请求有什么用途?</h4><ol>
<li>制作单页面应用,用户操作不进行跳转、每次只更新局部内容</li>
<li>表单即时校验,如文本框失去焦点立即检验</li>
<li>进行前后端分离,后端只关注数据</li>
<li>定时异步请求(轮询),实现伪实时效果,如在线聊天室</li>
<li>异步加载多级数据,如树形结构、多级联动菜单、分页</li>
<li>……</li>
</ol>
<p><strong>问题:前端如何处理大数据?</strong><br>解析:前端数据再大,还是要向服务器端请求数据,浏览器还是要解析,其实没法从根本上解决问题。如果页面上的dom节点多了,浏览器可能就处理不过来,造成浏览器假死现象。<br>一个方案就是:异步加载完这些数据,来进行异步处理,这样可以减轻浏览器的压力。</p>
<h4 id="1-4__u5F02_u6B65_u8BF7_u6C42_u7684_u4F18_u7F3A_u70B9"><a href="#1-4__u5F02_u6B65_u8BF7_u6C42_u7684_u4F18_u7F3A_u70B9" class="headerlink" title="1.4 异步请求的优缺点"></a>1.4 异步请求的优缺点</h4><p><strong>优点:</strong><br> 1.不会阻塞当前正在进行的任务。<br> 2.局部刷新,避免页面跳转,用户体验更好<br> 3.减少请求数据的大小,加载更快<br> 4.有利于前后端分离,后端只关注数据</p>
<p><strong>缺陷:</strong><br> 1.毁坏浏览器前进后退按钮的功能<br> 2.不利于SEO<br> 3.无法跨域</p>
<p>这些都有相应的解决方法</p>
<h4 id="1-5__u8BA4_u8BC6XMLHttpRequest_u5BF9_u8C61"><a href="#1-5__u8BA4_u8BC6XMLHttpRequest_u5BF9_u8C61" class="headerlink" title="1.5 认识XMLHttpRequest对象"></a>1.5 认识XMLHttpRequest对象</h4><p>我们可以创建一个实例,并在控制台里面打印</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> xhr = <span class="keyword">new</span> XMLHttpRequest();</span><br><span class="line"><span class="built_in">console</span>.log(xhr);</span><br></pre></td></tr></table></figure>
<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><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">① 字段</span><br><span class="line">onreadystatechange:null 请求的状态发生变化时的属性</span><br><span class="line">readyState:0 请求的状态</span><br><span class="line">responseText:"" 服务器返回的东西</span><br><span class="line">status:0 对应http状态码</span><br><span class="line">textStatus 会告诉你error的类型</span><br><span class="line"></span><br><span class="line">② 原型方法</span><br><span class="line">abort() 取消请求。</span><br><span class="line">open() 建立一个连接</span><br><span class="line">send() 发送请求</span><br><span class="line">setRequestHeader() 设置请求头部</span><br></pre></td></tr></table></figure>
<h4 id="1-6__u539F_u751Fajax_u5199_u6CD5"><a href="#1-6__u539F_u751Fajax_u5199_u6CD5" class="headerlink" title="1.6 原生ajax写法"></a>1.6 原生ajax写法</h4><p>需要注意的是原生XMLHttpRequest不兼容低版本IE6及以下,所以还需要考虑低版本的IE的兼容性。<br>兼容IE6的写法: ActiveXObject(‘Microsoft.XMLHTTP’)。<br>兼容IE5的写法: ActiveXObject(‘MSXML2.XMLHTTP’)。</p>
<p>以下是做了兼容性处理的原生请求的创建:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">createXMLHTTPRequest</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="comment">//1.创建XMLHttpRequest对象 </span></span><br><span class="line"> <span class="comment">//这是XMLHttpReuquest对象无部使用中最复杂的一步 </span></span><br><span class="line"> <span class="comment">//需要针对IE和其他类型的浏览器建立这个对象的不同方式写不同的代码 </span></span><br><span class="line"> <span class="keyword">var</span> xhr;</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">window</span>.XMLHttpRequest) {</span><br><span class="line"> <span class="comment">//针对FireFox,Mozillar,Opera,Safari,IE7,IE8 </span></span><br><span class="line"> xhr = <span class="keyword">new</span> XMLHttpRequest();</span><br><span class="line"> <span class="comment">//针对某些特定版本的mozillar浏览器的BUG进行修正 </span></span><br><span class="line"> <span class="keyword">if</span> (xhr.overrideMimeType) {</span><br><span class="line"> xhr.overrideMimeType(<span class="string">"text/xml"</span>);</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (<span class="built_in">window</span>.ActiveXObject) {</span><br><span class="line"> <span class="comment">//针对IE6,IE5.5,IE5 </span></span><br><span class="line"> <span class="comment">//两个可以用于创建XMLHTTPRequest对象的控件名称,保存在一个js的数组中 </span></span><br><span class="line"> <span class="comment">//排在前面的版本较新 </span></span><br><span class="line"> <span class="keyword">var</span> activexName = [<span class="string">"Microsoft.XMLHTTP"</span>,<span class="string">"MSXML2.XMLHTTP"</span>];</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i < activexName.length; i++) {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="comment">//取出一个控件名进行创建,如果创建成功就终止循环 </span></span><br><span class="line"> <span class="comment">//如果创建失败,回抛出异常,然后可以继续循环,继续尝试创建 </span></span><br><span class="line"> xhr = <span class="keyword">new</span> ActiveXObject(activexName[i]);</span><br><span class="line"> <span class="keyword">if</span> (xhr) {</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">catch</span> (e) {}</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> xhr;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>GET请求用法:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> req = createXMLHTTPRequest();</span><br><span class="line"><span class="keyword">if</span> (req) {</span><br><span class="line"> req.open(<span class="string">"GET"</span>, <span class="string">"http://test.com/?keywords=test"</span>, <span class="literal">true</span>);</span><br><span class="line"> req.onreadystatechange = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (req.readyState == <span class="number">4</span>) {</span><br><span class="line"> <span class="keyword">if</span> (req.status == <span class="number">200</span>) {</span><br><span class="line"> alert(<span class="string">"success"</span>);</span><br><span class="line"> <span class="comment">//主动释放,js本身也会回收</span></span><br><span class="line"> xhr = <span class="literal">null</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> alert(<span class="string">"error"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> req.send(<span class="literal">null</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>POST请求用法:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> req = createXMLHTTPRequest();</span><br><span class="line"><span class="keyword">if</span>(req){</span><br><span class="line"> req.open(<span class="string">"POST"</span>, <span class="string">"http://test.com/"</span>, <span class="literal">true</span>);</span><br><span class="line"> <span class="comment">//post请求需要设置请求头</span></span><br><span class="line"> req.setRequestHeader(<span class="string">"Content-Type"</span>,<span class="string">"application/x-www-form-urlencoded"</span>); </span><br><span class="line"> req.send(<span class="string">"keywords=test"</span>);</span><br><span class="line"> req.onreadystatechange = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">if</span>(req.readyState == <span class="number">4</span>){</span><br><span class="line"> <span class="keyword">if</span>(req.status == <span class="number">200</span>){</span><br><span class="line"> alert(<span class="string">"success"</span>);</span><br><span class="line"> <span class="comment">//主动释放,js本身也会回收</span></span><br><span class="line"> xhr = <span class="literal">null</span>;</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> alert(<span class="string">"error"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p><strong>readyState值说明:请求分5个阶段,每个阶段有对应的readyState的值:</strong></p>
<ul>
<li>0-未初始化,send方法未调用</li>
<li>1-正在发送请求,send方法已调用</li>
<li>2-请求发送完毕,send方法执行完毕</li>
<li>3-正在解析响应内容(可以接收到部分响应数据)</li>
<li>4-响应内容解析完毕(数据接收完毕并且连接已经关闭)</li>
</ul>
<p><strong>status值说明:通常是用来判断服务器方的状态:</strong></p>
<ul>
<li>100——客户必须继续发出请求</li>
<li>101——客户要求服务器根据请求转换HTTP协议版本</li>
<li>200——成功</li>
<li>201——提示知道新文件的URL</li>
<li>300——请求的资源可在多处得到</li>
<li>301——删除请求数据</li>
<li>404——没有发现文件、查询或URl</li>
<li>500——服务器产生内部错误</li>
</ul>
<h3 id="2_jQuery_u4E2D_u7684ajax"><a href="#2_jQuery_u4E2D_u7684ajax" class="headerlink" title="2 jQuery中的ajax"></a>2 jQuery中的ajax</h3><p>jQuery中的ajax原理就是对原生的请求方法做了进一步封装和兼容性处理,包装成常用的方法:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">$.ajax()</span><br><span class="line">$.get()</span><br><span class="line">$.post()</span><br><span class="line">$.getJSON()</span><br><span class="line">$.getScript()</span><br><span class="line">$.fn.load()</span><br></pre></td></tr></table></figure>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><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><span class="line">$.ajax({</span><br><span class="line"> url:<span class="string">'请求地址'</span>,</span><br><span class="line"> type:<span class="string">'GET/POST'</span>,</span><br><span class="line"> <span class="keyword">async</span>: <span class="literal">true</span>/<span class="literal">false</span>, <span class="comment">//是否异步</span></span><br><span class="line"> data: {},<span class="comment">//发送的数据</span></span><br><span class="line"> timeout: <span class="string">'5000'</span>,<span class="comment">//超时时间</span></span><br><span class="line"> dataType: <span class="string">'json/xml/html/script/json/jsonp/text'</span></span><br><span class="line"> <span class="comment">//返回的数据格式</span></span><br><span class="line"> beforeSend: <span class="function"><span class="keyword">function</span>(<span class="params">xhr</span>)</span>{},<span class="comment">//发送请求前</span></span><br><span class="line"> success: <span class="function"><span class="keyword">function</span>(<span class="params">data, textStatus, jqXHR</span>)</span>{},<span class="comment">//请求成功</span></span><br><span class="line"> error: <span class="function"><span class="keyword">function</span>(<span class="params">xhr, textStatus</span>)</span>{},<span class="comment">//请求失败</span></span><br><span class="line"> complete: <span class="function"><span class="keyword">function</span>(<span class="params">xhr, testStatus</span>)</span>{},<span class="comment">//请求结束</span></span><br><span class="line">})</span><br></pre></td></tr></table></figure>
<p>通常情况下使用$.ajax,因为他稍微更底层一点,可配置性高一点,可控性也高一点,效率也高一些。</p>
<h3 id="3_Ajax_u4E2D_u7684_u5168_u5C40_u914D_u7F6E_u548C_u5168_u5C40_u4E8B_u4EF6"><a href="#3_Ajax_u4E2D_u7684_u5168_u5C40_u914D_u7F6E_u548C_u5168_u5C40_u4E8B_u4EF6" class="headerlink" title="3 Ajax中的全局配置和全局事件"></a>3 Ajax中的全局配置和全局事件</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">$.ajaxSetup({</span><br><span class="line"> type: <span class="string">'POST'</span>,</span><br><span class="line"> timeout:<span class="string">'6000'</span>,</span><br><span class="line"> data: {name: <span class="string">'abc'</span>},</span><br><span class="line"> dataType: <span class="string">'json'</span>,</span><br><span class="line"> beforSend: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'loading...'</span>);</span><br><span class="line"> },</span><br><span class="line"> error: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> alert(<span class="string">'请求失败,请重试!'</span>);</span><br><span class="line"> }</span><br><span class="line"> });</span><br></pre></td></tr></table></figure>
<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><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="title">script</span> <span class="attribute">type</span>=<span class="value">"text/javascript"</span>></span><span class="javascript"></span><br><span class="line"> $(<span class="built_in">document</span>).ajaxStart(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="comment">/* Stuff to do when an AJAX call is started and no other AJAX calls are in progress */</span>;</span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> $(<span class="built_in">document</span>).ajaxSend(<span class="function"><span class="keyword">function</span>(<span class="params">event, xhr, settings</span>) </span>{</span><br><span class="line"> <span class="comment">/* stuff to do before an AJAX request is sent */</span>;</span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> $(<span class="built_in">document</span>).ajaxSuccess(<span class="function"><span class="keyword">function</span>(<span class="params">event, xhr, settings</span>) </span>{</span><br><span class="line"> <span class="comment">/* executes whenever an AJAX request completes successfully */</span></span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> $(<span class="built_in">document</span>).ajaxError(<span class="function"><span class="keyword">function</span>(<span class="params">event, xhr, settings, thrownError</span>) </span>{</span><br><span class="line"> <span class="comment">/* Stuff to do when an AJAX call returns an error */</span>;</span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> $(<span class="built_in">document</span>).ajaxComplete(<span class="function"><span class="keyword">function</span>(<span class="params">event, xhr, settings</span>) </span>{</span><br><span class="line"> <span class="comment">/* executes whenever an AJAX request completes */</span></span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> $(<span class="built_in">document</span>).ajaxStop((<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="comment">/* stuff to do when all AJAX calls have completed */</span>;</span><br><span class="line"> });</span><br><span class="line"></span><span class="tag"></<span class="title">script</span>></span></span><br></pre></td></tr></table></figure>
<p>可以通过Ajax全局事件写一个漂亮的显示请求进度的<a href="http://iwuly.com/snippets/?searchId=001">DEMO</a></p>
<h3 id="4__u8868_u5355_u6570_u636E_u5E8F_u5217_u5316"><a href="#4__u8868_u5355_u6570_u636E_u5E8F_u5217_u5316" class="headerlink" title="4 表单数据序列化"></a>4 表单数据序列化</h3><p><strong>作用:</strong><br>1.异步提交表单,免去跳转<br>2.快速获取表单数据<br>jQuery中的方法<br>serializ()//序列化为字符串<br>serializeArray()//序列化为数组</p>
<p>这两个不是jQuery中的方法<br>IE7以下需要引入JSON2文件<br>JSON对象呢在HTML5里面已经列为标准了呢。IE6还不能支持。所以还需要依赖JSON2文件<br>JSON.parse()//json字符串转化为json对象<br>JSON.stringify()//json对象转为json字符串</p>
<h3 id="5__u5B9E_u9645_u5E94_u7528_u4E2D_u7684_u6CE8_u610F_u4E8B_u9879"><a href="#5__u5B9E_u9645_u5E94_u7528_u4E2D_u7684_u6CE8_u610F_u4E8B_u9879" class="headerlink" title="5 实际应用中的注意事项"></a>5 实际应用中的注意事项</h3><h4 id="5-1__u51FD_u6570return_u5F02_u6B65_u6570_u636E_uFF0C_u53D6_u4E0D_u5230_u7684_u95EE_u9898"><a href="#5-1__u51FD_u6570return_u5F02_u6B65_u6570_u636E_uFF0C_u53D6_u4E0D_u5230_u7684_u95EE_u9898" class="headerlink" title="5.1 函数return异步数据,取不到的问题"></a>5.1 函数return异步数据,取不到的问题</h4><p>可以设置为同步请求,或者返回promise。</p>
<h4 id="5-2__u540C_u6B65Ajax_u8BF7_u6C42_u9020_u6210_u7684UI_u7EBF_u7A0B_u963B_u585E_u95EE_u9898"><a href="#5-2__u540C_u6B65Ajax_u8BF7_u6C42_u9020_u6210_u7684UI_u7EBF_u7A0B_u963B_u585E_u95EE_u9898" class="headerlink" title="5.2 同步Ajax请求造成的UI线程阻塞问题"></a>5.2 同步Ajax请求造成的UI线程阻塞问题</h4><p>一个浏览器嘛,他分为两个引擎,一个是js引擎用来解析你的js代码,比方说chrome的js引擎是v8,UI引擎是webkit,一个浏览器么,一个js引擎,一个ui引擎。这两个是没法同时进行的。一个运行的时候,他会阻塞吊另一个。什么意思呢。发送同步请求的时候,比如2秒钟的时候,js引擎要工作2s钟的时间,他会把ui引擎给阻塞掉,所以gif图片他是需要ui引擎来渲染的,所以他会阻塞掉的。(阻塞时,js,animate照常运行,但是页面呈现出的是2s后的效果)。为什么我们平时感受不到js引擎把UI引擎给阻塞掉了?因为同步的代码是非常快的。第一个例子执行100万次才10几毫秒,所以你感受不到。但是2s种你就能做好多事情。</p>
<h4 id="5-3__u4E3AAjax_u8BBE_u7F6E_u65F6_u95F4_u8D85_u65F6"><a href="#5-3__u4E3AAjax_u8BBE_u7F6E_u65F6_u95F4_u8D85_u65F6" class="headerlink" title="5.3 为Ajax设置时间超时"></a>5.3 为Ajax设置时间超时</h4><p>参考Ajax全局配置章节。</p>
<h4 id="5-4__u5224_u65ADerror_u7C7B_u578B"><a href="#5-4__u5224_u65ADerror_u7C7B_u578B" class="headerlink" title="5.4 判断error类型"></a>5.4 判断error类型</h4><p>error的类型可能有:<br>timeout 超时<br>error 获取不到具体错误(请求时浏览器刷新报error错误)<br>notmodified 返回304<br>parsererror 解析xml或json错误<br>abort 请求取消</p>
<h3 id="6__u6269_u5C55_u77E5_u8BC6"><a href="#6__u6269_u5C55_u77E5_u8BC6" class="headerlink" title="6 扩展知识"></a>6 扩展知识</h3><ul>
<li>HTML5的XMLHttpRequest2</li>
<li>promise规范和jQuery的Deffered对象</li>
<li>pjax</li>
<li>跨域请求</li>
<li>Fetch</li>
</ul>
<h3 id="7__u53C2_u8003_u8D44_u6599"><a href="#7__u53C2_u8003_u8D44_u6599" class="headerlink" title="7 参考资料"></a>7 参考资料</h3><ul>
<li><a href="http://www.iqiyi.com/w_19rscqwj2d.html" target="_blank" rel="external">ajax全面解析</a></li>
<li><a href="http://sjpsega.iteye.com/blog/1729350" target="_blank" rel="external">原生ajax写法</a></li>
</ul>
]]></content>
<summary type="html">
<![CDATA[<h3 id="u524D_u8A00"><a href="#u524D_u8A00" class="headerlink" title="前言"></a>前言</h3><p>前段时间群里做知识分享,<a href="http://www.cnblogs.com/lvdabao/">大豹</a>老师分享了他对Ajax的一些心得体会,当时听的比较入迷,整理了一些笔记,希望对大家有帮助。</p>
<h3 id="u77E5_u8BC6_u76EE_u5F55_u7ED3_u6784"><a href="#u77E5_u8BC6_u76EE_u5F55_u7ED3_u6784" class="headerlink" title="知识目录结构"></a>知识目录结构</h3><ul>
<li>Ajax 基础知识</li>
<li>jQuery中Ajax的相关用法</li>
<li>jQuery中Ajax全局设置和全局事件</li>
<li>表单数据序列化</li>
<li>实际应用中的注意事项</li>
<li>知识扩展</li>
<li>参考资料]]>
</summary>
<category term="Ajax" scheme="http://iwuly.com/tags/Ajax/"/>
<category term="javaScript" scheme="http://iwuly.com/tags/javaScript/"/>
</entry>
<entry>
<title><![CDATA[从零天梯:重绘(redraw)和重排(reflow)]]></title>
<link href="http://iwuly.com/2014/09/06/%E4%BB%8E%E9%9B%B6%E5%A4%A9%E6%A2%AF%E7%B3%BB%E5%88%97/%E9%87%8D%E7%BB%98%E5%92%8C%E9%87%8D%E6%8E%92/"/>
<id>http://iwuly.com/2014/09/06/从零天梯系列/重绘和重排/</id>
<published>2014-09-06T12:26:04.000Z</published>
<updated>2016-10-08T15:22:20.000Z</updated>
<content type="html"><![CDATA[<p>记忆关键词:重绘、重排、渲染、DOM树、性能</p>
<h3 id="u8FC7_u7A0B_3A"><a href="#u8FC7_u7A0B_3A" class="headerlink" title="过程:"></a>过程:</h3><p> ① HTML文档->② DOM树 ->③ 渲染树 ->④ 页面<br><a id="more"></a></p>
<h3 id="u89E3_u6790_3A"><a href="#u89E3_u6790_3A" class="headerlink" title="解析:"></a>解析:</h3><ul>
<li>①->②:浏览器下载文档后根据HTML文档构建DOM树。<blockquote>
<p>(在DOM树中,每一个HTML标签都有一个对应的节点,并且每一个文本也都会有一个对应的文本节点。 DOM树的根节点就是 documentElement,对应的是html标签。)</p>
</blockquote>
</li>
<li>②->③:之后根据DOM元素的几何属性构建一棵用于渲染的树。<blockquote>
<p>(对CSS代码中非法的语法她会直接忽略掉.解析CSS的时候会按照如下顺序来定义优先级:浏览器默认设置,用户设置,外链样式,内联样式,html中的style。)</p>
</blockquote>
</li>
<li>③->④:当渲染树构建完成后,浏览器就可以将元素放置到正确的位置,再根据渲染树节点的样式属性绘制出页面。</li>
</ul>
<h3 id="u573A_u666F"><a href="#u573A_u666F" class="headerlink" title="场景"></a>场景</h3><ul>
<li>引起重绘:一个节点元素外观的改变绘(visibility、outline、背景色等属性)</li>
<li><p>引起重排:</p>
<blockquote>
<p>1.DOM元素的几何属性变化(宽高) (ps:可能引起子父节点、兄弟节点甚至整个文档的重新计算、性能代价昂贵)<br>2.DOM树的结构变化(节点的增删改查)<br>3.获取某些属性(offsetXXX、scrollXXX、clientXXX)<br>ps:在多次使用这些值时应进行缓存<br>4.改变元素的一些样式,调整浏览器窗口大小等等</p>
</blockquote>
<p>重排是更明显的一种改变,可以理解为渲染树需要重新计算;<br>重排的代价高于重绘。重排时会引起重绘。</p>
</li>
</ul>
<h3 id="u4E3A_u4EC0_u4E48_u8981_u907F_u514D_u4F7F_u7528table_u505A_u5E03_u5C40_uFF1F"><a href="#u4E3A_u4EC0_u4E48_u8981_u907F_u514D_u4F7F_u7528table_u505A_u5E03_u5C40_uFF1F" class="headerlink" title="为什么要避免使用table做布局?"></a>为什么要避免使用table做布局?</h3><p>正常的流布局,对渲染树的计算通常只需要遍历一次就可以完成。但table及其内部元素除外,通常要花3倍的时间才能确定好其在渲染树中节点的属性。这也是为什么我们要避免使用table做布局的一个原因。</p>
<h3 id="u9488_u5BF9_u51CF_u5C11_u91CD_u7ED8_u548C_u91CD_u6392_u7684_u4E00_u4E9B_u4F18_u5316_uFF1A"><a href="#u9488_u5BF9_u51CF_u5C11_u91CD_u7ED8_u548C_u91CD_u6392_u7684_u4E00_u4E9B_u4F18_u5316_uFF1A" class="headerlink" title="针对减少重绘和重排的一些优化:"></a>针对减少重绘和重排的一些优化:</h3><ol>
<li>将多次改变样式属性的操作合并成一次操作</li>
<li>使操作次数多的元素脱离了文档流,它的变化不会影响到其他元素。</li>
<li>在内存中多次操作节点,完成后再添加到文档中去。</li>
<li>由于display属性为none的元素不在渲染树中,对隐藏的元素操作不会引发其他元素的重排。如果要对一个元素进行复杂的操作时,可以先隐藏它,操作完成后再显示。这样只在隐藏和显示时触发2次重排。</li>
<li>在需要经常获取那些引起浏览器重排的属性值时,要缓存到变量。</li>
</ol>
<h3 id="u77E5_u8BC6_u5DE9_u56FA_uFF1A"><a href="#u77E5_u8BC6_u5DE9_u56FA_uFF1A" class="headerlink" title="知识巩固:"></a>知识巩固:</h3><p>在前端如何实现一个表格的排序(尽可能减少重绘和重排的影响)。<br>以下是我个人的想法,如有考虑不周的情况,欢迎在评论区留言~大家一起进步~</p>
<blockquote>
<p>1.获取表格数据:获取鼠标点击的表头单元格的列号,遍历数据行,获取行内数据,以数组形式缓存起来<br>2.对数据排序:根据关键字对数组排序。<br>3.对排序好的数据进行字符串拼接。用一个变量保存拼接好的字符串内容。<br>4.清空tbody中的内容,插入已拼接好的内容。</p>
</blockquote>
<h3 id="u53C2_u8003_u6587_u6863_uFF1A"><a href="#u53C2_u8003_u6587_u6863_uFF1A" class="headerlink" title="参考文档:"></a>参考文档:</h3><p><a href="http://kb.cnblogs.com/page/169820/" target="_blank" rel="external">http://kb.cnblogs.com/page/169820/</a><br><a href="http://blog.csdn.net/lihongxun945/article/details/37830667" target="_blank" rel="external">http://blog.csdn.net/lihongxun945/article/details/37830667</a></p>
]]></content>
<summary type="html">
<![CDATA[<p>记忆关键词:重绘、重排、渲染、DOM树、性能</p>
<h3 id="u8FC7_u7A0B_3A"><a href="#u8FC7_u7A0B_3A" class="headerlink" title="过程:"></a>过程:</h3><p> ① HTML文档->② DOM树 ->③ 渲染树 ->④ 页面<br>]]>
</summary>
<category term="html" scheme="http://iwuly.com/tags/html/"/>
<category term="重排" scheme="http://iwuly.com/tags/%E9%87%8D%E6%8E%92/"/>
</entry>
<entry>
<title><![CDATA[Hello World]]></title>
<link href="http://iwuly.com/2014/09/02/Hello/"/>
<id>http://iwuly.com/2014/09/02/Hello/</id>
<published>2014-09-02T11:16:07.000Z</published>
<updated>2016-10-08T15:21:37.000Z</updated>
<content type="html"><![CDATA[<p> 阳阳(Keraun)于2014-09-02开始运行这个小站,后续会逐步建设,欢迎大家来访^_^</p>
]]></content>
<summary type="html">
<![CDATA[<p> 阳阳(Keraun)于2014-09-02开始运行这个小站,后续会逐步建设,欢迎大家来访^_^</p>
]]>
</summary>
</entry>
</feed>