-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
607 lines (447 loc) · 88.4 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="description" content="在前端的道路上砥砺前行,Just do IT">
<link rel="stylesheet" href="/bower_components/fancybox/source/jquery.fancybox.css">
<link rel="stylesheet" href="/bower_components/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="/css/style.css">
<title>四面的博客 - 做一枚有用的前端工程师</title>
</head>
<body>
<header id="header">
<div class="center">
<div class="wrap">
<div id="site">
<h1>
<a href="/">四面的博客</a>
<a class="github" href="https://github.com/dnxbf321">
<svg aria-hidden="true" class="octicon octicon-mark-github" height="28" role="img" version="1.1" viewBox="0 0 16 16" width="28"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59 0.4 0.07 0.55-0.17 0.55-0.38 0-0.19-0.01-0.82-0.01-1.49-2.01 0.37-2.53-0.49-2.69-0.94-0.09-0.23-0.48-0.94-0.82-1.13-0.28-0.15-0.68-0.52-0.01-0.53 0.63-0.01 1.08 0.58 1.23 0.82 0.72 1.21 1.87 0.87 2.33 0.66 0.07-0.52 0.28-0.87 0.51-1.07-1.78-0.2-3.64-0.89-3.64-3.95 0-0.87 0.31-1.59 0.82-2.15-0.08-0.2-0.36-1.02 0.08-2.12 0 0 0.67-0.21 2.2 0.82 0.64-0.18 1.32-0.27 2-0.27 0.68 0 1.36 0.09 2 0.27 1.53-1.04 2.2-0.82 2.2-0.82 0.44 1.1 0.16 1.92 0.08 2.12 0.51 0.56 0.82 1.27 0.82 2.15 0 3.07-1.87 3.75-3.65 3.95 0.29 0.25 0.54 0.73 0.54 1.48 0 1.07-0.01 1.93-0.01 2.2 0 0.21 0.15 0.46 0.55 0.38C13.71 14.53 16 11.53 16 8 16 3.58 12.42 0 8 0z"></path></svg>
</a>
</h1>
<h2>
<a href="/">做一枚有用的前端工程师</a>
</h2>
</div>
<nav id="menu">
<ul>
<li><a href="/">首页</a></li>
<li><a href="/archives/">归档</a></li>
</ul>
</nav>
</div>
</div>
</header>
<div id="content">
<div class="center">
<div class="main-col">
<article class="post">
<div class="post-content">
<header>
<div class="meta">
<div class="icon">
<i class="fa fa-file"></i>
</div>
<time datetime="2016-02-26T05:48:00.000Z">2016-02-26</time>
</div>
<h1 class="title" data-role="articleTitle"><a href="/2016/02/26/函数作用域修改大法/">函数作用域修改大法</a></h1>
</header>
<div class="entry">
<ul>
<li><p>Function.prototype.bind()</p>
<p>bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind() 方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。</p>
<p>语法</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span><br><span class="line"> * thisArg</span><br><span class="line"> * 当绑定函数被调用时,该参数会作为原函数运行时的 this 指向。当使用new 操作符调用绑定函数时,该参数无效。</span><br><span class="line"> * arg1, arg2, ...</span><br><span class="line"> * 当绑定函数被调用时,这些参数加上绑定函数本身的参数会按照顺序作为原函数运行时的参数。</span><br><span class="line"> */</span></span><br><span class="line">fun.bind(thisArg[, arg1[, arg2[, ...]]])</span><br></pre></td></tr></table></figure>
<p>支持情况:ie >= 9、chrome、safari。</p>
<p>举例(摘自<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind" target="_blank" rel="external">MDN</a>):</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">LateBloomer</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">this</span>.petalCount = <span class="built_in">Math</span>.ceil(<span class="built_in">Math</span>.random() * <span class="number">12</span>) + <span class="number">1</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// Declare bloom after a delay of 1 second</span></span><br><span class="line">LateBloomer.prototype.bloom = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">window</span>.setTimeout(<span class="keyword">this</span>.declare.bind(<span class="keyword">this</span>), <span class="number">1000</span>);</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line">LateBloomer.prototype.declare = <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">'I am a beautiful flower with '</span> +</span><br><span class="line"> <span class="keyword">this</span>.petalCount + <span class="string">' petals!'</span>);</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> flower = <span class="keyword">new</span> LateBloomer();</span><br><span class="line">flower.bloom(); <span class="comment">// 一秒钟后, 调用'declare'方法</span></span><br></pre></td></tr></table></figure>
<p>为了兼容低版本浏览器,可以使用如下 polyfill</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (!<span class="built_in">Function</span>.prototype.bind) {</span><br><span class="line"> <span class="built_in">Function</span>.prototype.bind = <span class="function"><span class="keyword">function</span> (<span class="params">oThis</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> <span class="keyword">this</span> !== <span class="string">"function"</span>) {</span><br><span class="line"> <span class="comment">// closest thing possible to the ECMAScript 5</span></span><br><span class="line"> <span class="comment">// internal IsCallable function</span></span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">TypeError</span>(<span class="string">"Function.prototype.bind - what is trying to be bound is not callable"</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">var</span> aArgs = <span class="built_in">Array</span>.prototype.slice.call(<span class="built_in">arguments</span>, <span class="number">1</span>),</span><br><span class="line"> fToBind = <span class="keyword">this</span>,</span><br><span class="line"> fNOP = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{},</span><br><span class="line"> fBound = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> fToBind.apply(<span class="keyword">this</span> <span class="keyword">instanceof</span> fNOP</span><br><span class="line"> ? <span class="keyword">this</span></span><br><span class="line"> : oThis || <span class="keyword">this</span>,</span><br><span class="line"> aArgs.concat(<span class="built_in">Array</span>.prototype.slice.call(<span class="built_in">arguments</span>)));</span><br><span class="line"> };</span><br><span class="line"></span><br><span class="line"> fNOP.prototype = <span class="keyword">this</span>.prototype;</span><br><span class="line"> fBound.prototype = <span class="keyword">new</span> fNOP();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> fBound;</span><br><span class="line"> };</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
</li>
<li><p>Function.prototype.call 和 Function.prototype.apply</p>
<p>举例(摘自<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call" target="_blank" rel="external">MDN</a>):</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Product</span>(<span class="params">name, price</span>) </span>{</span><br><span class="line"> <span class="keyword">this</span>.name = name;</span><br><span class="line"> <span class="keyword">this</span>.price = price;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (price < <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="built_in">RangeError</span>(<span class="string">'Cannot create product '</span> +</span><br><span class="line"> <span class="keyword">this</span>.name + <span class="string">' with a negative price'</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Food</span>(<span class="params">name, price</span>) </span>{</span><br><span class="line"> Product.call(<span class="keyword">this</span>, name, price);</span><br><span class="line"> <span class="keyword">this</span>.category = <span class="string">'food'</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Toy</span>(<span class="params">name, price</span>) </span>{</span><br><span class="line"> Product.call(<span class="keyword">this</span>, name, price);</span><br><span class="line"> <span class="keyword">this</span>.category = <span class="string">'toy'</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> cheese = <span class="keyword">new</span> Food(<span class="string">'feta'</span>, <span class="number">5</span>);</span><br><span class="line"><span class="keyword">var</span> fun = <span class="keyword">new</span> Toy(<span class="string">'robot'</span>, <span class="number">40</span>);</span><br></pre></td></tr></table></figure>
</li>
<li><p>$.proxy(fn, context[, arg1[, arg2[, …]]])</p>
<p>这里使用的 jQuery 方法,接受两个参数,第一个为输入的函数,第二个为要绑定到的作用域,之后的参数加上绑定函数本身的参数会按照顺序作为原函数运行时的参数。此方法返回一个作用域为 context 的新函数。</p>
<p>举例(摘自<a href="https://api.jquery.com/jQuery.proxy/" target="_blank" rel="external">jQuery</a>):</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><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line"><span class="doctype"><!doctype html></span></span><br><span class="line"><span class="tag"><<span class="title">html</span> <span class="attribute">lang</span>=<span class="value">"en"</span>></span></span><br><span class="line"><span class="tag"><<span class="title">head</span>></span></span><br><span class="line"> <span class="tag"><<span class="title">meta</span> <span class="attribute">charset</span>=<span class="value">"utf-8"</span>></span></span><br><span class="line"> <span class="tag"><<span class="title">title</span>></span>jQuery.proxy demo<span class="tag"></<span class="title">title</span>></span></span><br><span class="line"> <span class="tag"><<span class="title">script</span> <span class="attribute">src</span>=<span class="value">"https://code.jquery.com/jquery-1.10.2.js"</span>></span><span class="undefined"></span><span class="tag"></<span class="title">script</span>></span></span><br><span class="line"><span class="tag"></<span class="title">head</span>></span></span><br><span class="line"><span class="tag"><<span class="title">body</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="title">p</span>></span><span class="tag"><<span class="title">button</span> <span class="attribute">type</span>=<span class="value">"button"</span> <span class="attribute">id</span>=<span class="value">"test"</span>></span>Test<span class="tag"></<span class="title">button</span>></span><span class="tag"></<span class="title">p</span>></span></span><br><span class="line"><span class="tag"><<span class="title">div</span> <span class="attribute">id</span>=<span class="value">"log"</span>></span><span class="tag"></<span class="title">div</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="title">script</span>></span><span class="javascript"></span><br><span class="line"><span class="keyword">var</span> me = {</span><br><span class="line"> type: <span class="string">"zombie"</span>,</span><br><span class="line"> test: <span class="function"><span class="keyword">function</span>(<span class="params"> event </span>) </span>{</span><br><span class="line"> <span class="comment">// Without proxy, `this` would refer to the event target</span></span><br><span class="line"> <span class="comment">// use event.target to reference that element.</span></span><br><span class="line"> <span class="keyword">var</span> element = event.target;</span><br><span class="line"> $( element ).css( <span class="string">"background-color"</span>, <span class="string">"red"</span> );</span><br><span class="line"></span><br><span class="line"> <span class="comment">// With proxy, `this` refers to the me object encapsulating</span></span><br><span class="line"> <span class="comment">// this function.</span></span><br><span class="line"> $( <span class="string">"#log"</span> ).append( <span class="string">"Hello "</span> + <span class="keyword">this</span>.type + <span class="string">"<br>"</span> );</span><br><span class="line"> $( <span class="string">"#test"</span> ).off( <span class="string">"click"</span>, <span class="keyword">this</span>.test );</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> you = {</span><br><span class="line"> type: <span class="string">"person"</span>,</span><br><span class="line"> test: <span class="function"><span class="keyword">function</span>(<span class="params"> event </span>) </span>{</span><br><span class="line"> $( <span class="string">"#log"</span> ).append( <span class="keyword">this</span>.type + <span class="string">" "</span> );</span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="comment">// Execute you.test() in the context of the `you` object</span></span><br><span class="line"><span class="comment">// no matter where it is called</span></span><br><span class="line"><span class="comment">// i.e. the `this` keyword will refer to `you`</span></span><br><span class="line"><span class="keyword">var</span> youClick = $.proxy( you.test, you );</span><br><span class="line"></span><br><span class="line"><span class="comment">// attach click handlers to #test</span></span><br><span class="line">$( <span class="string">"#test"</span> )</span><br><span class="line"> <span class="comment">// this === "zombie"; handler unbound after first click</span></span><br><span class="line"> .on( <span class="string">"click"</span>, $.proxy( me.test, me ) )</span><br><span class="line"></span><br><span class="line"> <span class="comment">// this === "person"</span></span><br><span class="line"> .on( <span class="string">"click"</span>, youClick )</span><br><span class="line"></span><br><span class="line"> <span class="comment">// this === "zombie"</span></span><br><span class="line"> .on( <span class="string">"click"</span>, $.proxy( you.test, me ) )</span><br><span class="line"></span><br><span class="line"> <span class="comment">// this === "<button> element"</span></span><br><span class="line"> .on( <span class="string">"click"</span>, you.test );</span><br><span class="line"></span><span class="tag"></<span class="title">script</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"></<span class="title">body</span>></span></span><br><span class="line"><span class="tag"></<span class="title">html</span>></span></span><br></pre></td></tr></table></figure>
</li>
</ul>
</div>
<footer class="clearfix">
<div class="categories">
<i class="fa fa-folder"></i>
<a href="/categories/前端/">前端</a>
</div>
<div class="tags">
<i class="fa fa-tags"></i>
<a href="/tags/Javascript/">#Javascript</a>
<a href="/tags/前端/">#前端</a>
</div>
</footer>
</div>
</article>
<article class="post">
<div class="post-content">
<header>
<div class="meta">
<div class="icon">
<i class="fa fa-file"></i>
</div>
<time datetime="2016-02-24T07:15:28.000Z">2016-02-24</time>
</div>
<h1 class="title" data-role="articleTitle"><a href="/2016/02/24/Javascript Setters and Getters/">Javascript Getters and Setters</a></h1>
</header>
<div class="entry">
<p>Getters 和 setters 是用来读取和设置数据非常好的方式。比方说,你需要从一个对象中读取和设置一个值,如下代码:<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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">Field</span>(<span class="params">val</span>)</span>{</span><br><span class="line"> <span class="keyword">var</span> a = val;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">this</span>.getValue = <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">this</span>.setValue = <span class="function"><span class="keyword">function</span>(<span class="params">val</span>)</span>{</span><br><span class="line"> a = val;</span><br><span class="line"> };</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> field = <span class="keyword">new</span> Field(<span class="string">"test"</span>);</span><br><span class="line">field.value</span><br><span class="line"><span class="comment">// => undefined</span></span><br><span class="line">field.setValue(<span class="string">"test2"</span>)</span><br><span class="line">field.getValue()</span><br><span class="line"><span class="comment">// => "test2"</span></span><br></pre></td></tr></table></figure></p>
<p>我们可以使用到 getters 和 setters 来重写,重写的代码如下:<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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">Field</span>(<span class="params">val</span>)</span>{</span><br><span class="line"> <span class="keyword">this</span>.a = val;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">Field.prototype = {</span><br><span class="line"> get value() {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">this</span>.a;</span><br><span class="line"> },</span><br><span class="line"> set value(val) {</span><br><span class="line"> <span class="keyword">this</span>.a = val;</span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"><span class="keyword">var</span> field = <span class="keyword">new</span> Field(<span class="string">"test"</span>);</span><br><span class="line">field.value</span><br><span class="line"><span class="comment">// => "test"</span></span><br><span class="line">field.value = <span class="string">"test2"</span>;</span><br><span class="line"><span class="comment">// => "test2"</span></span><br></pre></td></tr></table></figure></p>
<p>可以看到,读取值和设置值都是如此简明。get、set 关键字后面的方法分别实现了对 this.a 的读取和设置。获取时 .value 即可,不加括号。设置时,使用 =,= 右边是要设置的值。</p>
<p>使用 getters、setters,让代码更加清晰,明确哪些值是可读的,哪些是可写的。</p>
<p>目前,chrome、safari、firfox、ie>=9 之后都是支持的。</p>
</div>
<footer class="clearfix">
<div class="categories">
<i class="fa fa-folder"></i>
<a href="/categories/前端/">前端</a>
</div>
<div class="tags">
<i class="fa fa-tags"></i>
<a href="/tags/Javascript/">#Javascript</a>
<a href="/tags/前端/">#前端</a>
</div>
</footer>
</div>
</article>
<article class="post">
<div class="post-content">
<header>
<div class="meta">
<div class="icon">
<i class="fa fa-file"></i>
</div>
<time datetime="2016-02-24T06:14:25.000Z">2016-02-24</time>
</div>
<h1 class="title" data-role="articleTitle"><a href="/2016/02/24/学习 koa/">学习 koa</a></h1>
</header>
<div class="entry">
<h2 id="背景">背景</h2><p>最近项目中首次使用 node 作为前端后台,便于同步渲染模板。项目中,少不了需要选择一个框架来充当骨架。对,我们选择的当红炸子鸡『koa』。</p>
<h2 id="基本用法">基本用法</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 引入 koa</span></span><br><span class="line"><span class="keyword">import</span> koa <span class="keyword">from</span> <span class="string">'koa'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 实例化 koa</span></span><br><span class="line"><span class="keyword">let</span> app = <span class="keyword">new</span> koa();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 请求返回 hello world</span></span><br><span class="line">app.use(<span class="function"><span class="keyword">function</span> *(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">this</span>.body = <span class="string">'Hello World'</span>;</span><br><span class="line">});</span><br><span class="line"></span><br><span class="line"><span class="comment">// 启动服务器,监听端口 3000</span></span><br><span class="line">app.listen(<span class="number">3000</span>);</span><br></pre></td></tr></table></figure>
<p>注意,我们使用了 es6 的语法,为了让 node 可以顺利运行,需要先引用 babel/register 。</p>
<p>概括起来,分三步走:</p>
<ol>
<li>引入并实例化 koa</li>
<li>往 koa 中插入中间件,如 koa-router、koa-static 中间件</li>
<li>启动服务</li>
</ol>
<h2 id="看源码">看源码</h2><p>以下是 koa/lib/Application.js 部分代码<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> app = Application.prototype;</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Application</span>(<span class="params"></span>) </span>{</span><br><span class="line"> ...</span><br><span class="line">};</span><br><span class="line"><span class="built_in">Object</span>.setPrototypeOf(Application.prototype, Emitter.prototype);</span><br><span class="line">app.listen = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> ...</span><br><span class="line">};</span><br><span class="line">app.use = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> ...</span><br><span class="line">};</span><br><span class="line">app.callback = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> ...</span><br><span class="line">};</span><br><span class="line">app.createContext = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> ...</span><br><span class="line">};</span><br><span class="line">app.onerror = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> ...</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>看到没有,代码毫无花哨可言,这不就是个普通的构造函数嘛!</p>
<p>下面我们逐个展开看代码</p>
<p>先上 Application function<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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">Application</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="comment">// 检查作用域 this,兼容 new koa() 和 koa() 两种调用方式。这行完全可以删掉,强烈建议程序员使用 new koa() 这种形式</span></span><br><span class="line"> <span class="keyword">if</span> (!(<span class="keyword">this</span> <span class="keyword">instanceof</span> Application)) <span class="keyword">return</span> <span class="keyword">new</span> Application;</span><br><span class="line"> <span class="comment">// 添加 env 对象到 this</span></span><br><span class="line"> <span class="keyword">this</span>.env = process.env.NODE_ENV || <span class="string">'development'</span>;</span><br><span class="line"> <span class="comment">// 添加 subdomainOffset 到 this</span></span><br><span class="line"> <span class="keyword">this</span>.subdomainOffset = <span class="number">2</span>;</span><br><span class="line"> <span class="comment">// 初始化 middleware</span></span><br><span class="line"> <span class="keyword">this</span>.middleware = [];</span><br><span class="line"> <span class="comment">// 将 context 对象添加到 this</span></span><br><span class="line"> <span class="keyword">this</span>.context = <span class="built_in">Object</span>.create(context); <span class="comment">// context = require('./context')</span></span><br><span class="line"> <span class="comment">// 将 request 对象添加到 this</span></span><br><span class="line"> <span class="keyword">this</span>.request = <span class="built_in">Object</span>.create(request); <span class="comment">// request = require('./request');</span></span><br><span class="line"> <span class="comment">// 将 response 对象添加到 this</span></span><br><span class="line"> <span class="keyword">this</span>.response = <span class="built_in">Object</span>.create(response); <span class="comment">// response = require('./response');</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Application.prototype = Emitter.prototype</span></span><br><span class="line"><span class="built_in">Object</span>.setPrototypeOf(Application.prototype, Emitter.prototype); <span class="comment">// Emitter = require('events').EventEmitter</span></span><br></pre></td></tr></table></figure>
<p>再看 app.use<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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="comment">/**</span><br><span class="line"> * 添加中间件</span><br><span class="line"> */</span></span><br><span class="line">app.use = <span class="function"><span class="keyword">function</span>(<span class="params">fn</span>)</span>{</span><br><span class="line"> <span class="comment">// 检查 fn 是否是 generator 函数,非将出现错误</span></span><br><span class="line"> <span class="keyword">if</span> (!<span class="keyword">this</span>.experimental) {</span><br><span class="line"> assert(fn && <span class="string">'GeneratorFunction'</span> == fn.constructor.name, <span class="string">'app.use() requires a generator function'</span>);</span><br><span class="line"> }</span><br><span class="line"> debug(<span class="string">'use %s'</span>, fn._name || fn.name || <span class="string">'-'</span>);</span><br><span class="line"> <span class="comment">// 将 fn 中间件保存到 middleware 数组中</span></span><br><span class="line"> <span class="keyword">this</span>.middleware.push(fn);</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">};</span><br></pre></td></tr></table></figure></p>
<p>再看 app.callback<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span><br><span class="line"> * 返回服务启动的回调方法</span><br><span class="line"> */</span></span><br><span class="line">app.callback = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="comment">// 且将 this.experimental 定义为 false,只看右边分支</span></span><br><span class="line"> <span class="comment">// compose = require('koa-compose')</span></span><br><span class="line"> <span class="comment">// compose 将 middleware 数组元素,包装成一个 generator 函数</span></span><br><span class="line"> <span class="comment">// co.wrap 将 generator 函数包装秤一个 promise 函数</span></span><br><span class="line"> <span class="keyword">var</span> fn = <span class="keyword">this</span>.experimental</span><br><span class="line"> ? compose_es7(<span class="keyword">this</span>.middleware)</span><br><span class="line"> : co.wrap(compose(<span class="keyword">this</span>.middleware));</span><br><span class="line"> <span class="keyword">var</span> self = <span class="keyword">this</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (!<span class="keyword">this</span>.listeners(<span class="string">'error'</span>).length) <span class="keyword">this</span>.on(<span class="string">'error'</span>, <span class="keyword">this</span>.onerror);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 返回函数</span></span><br><span class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params">req, res</span>)</span>{</span><br><span class="line"> res.statusCode = <span class="number">404</span>;</span><br><span class="line"> <span class="comment">// 创建作用域</span></span><br><span class="line"> <span class="keyword">var</span> ctx = self.createContext(req, res);</span><br><span class="line"> <span class="comment">// 监听 response,完成时执行回调 app.onerror 方法,将错误打印出来</span></span><br><span class="line"> onFinished(res, ctx.onerror);</span><br><span class="line"> <span class="comment">// 执行 fn,promise 状态为 resolve 时响应请求,将结果返回给请求方</span></span><br><span class="line"> fn.call(ctx).then(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> respond.call(ctx);</span><br><span class="line"> }).catch(ctx.onerror);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>再看 app.listen<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">app.listen = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> debug(<span class="string">'listen'</span>);</span><br><span class="line"> <span class="comment">// 创建 sever</span></span><br><span class="line"> <span class="keyword">var</span> server = http.createServer(<span class="keyword">this</span>.callback());</span><br><span class="line"> <span class="comment">// 将 server 开始监听工作</span></span><br><span class="line"> <span class="keyword">return</span> server.listen.apply(server, <span class="built_in">arguments</span>);</span><br><span class="line">};</span><br></pre></td></tr></table></figure></p>
<p>再看 app.createContext<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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="comment">/**</span><br><span class="line"> * 对 this.context 进行扩展,生成新的 context,作为中间件的作用域</span><br><span class="line"> */</span></span><br><span class="line">app.createContext = <span class="function"><span class="keyword">function</span>(<span class="params">req, res</span>)</span>{</span><br><span class="line"> <span class="keyword">var</span> context = <span class="built_in">Object</span>.create(<span class="keyword">this</span>.context);</span><br><span class="line"> <span class="keyword">var</span> request = context.request = <span class="built_in">Object</span>.create(<span class="keyword">this</span>.request);</span><br><span class="line"> <span class="keyword">var</span> response = context.response = <span class="built_in">Object</span>.create(<span class="keyword">this</span>.response);</span><br><span class="line"> context.app = request.app = response.app = <span class="keyword">this</span>;</span><br><span class="line"> context.req = request.req = response.req = req;</span><br><span class="line"> context.res = request.res = response.res = res;</span><br><span class="line"> request.ctx = response.ctx = context;</span><br><span class="line"> request.response = response;</span><br><span class="line"> response.request = request;</span><br><span class="line"> context.onerror = context.onerror.bind(context);</span><br><span class="line"> context.originalUrl = request.originalUrl = req.url;</span><br><span class="line"> context.cookies = <span class="keyword">new</span> Cookies(req, res, <span class="keyword">this</span>.keys);</span><br><span class="line"> context.accept = request.accept = accepts(req);</span><br><span class="line"> context.state = {};</span><br><span class="line"> <span class="keyword">return</span> context;</span><br><span class="line">};</span><br></pre></td></tr></table></figure></p>
<p>至此,Application.js 分析完毕。</p>
<p>再移步到 context.js。context.js 中初始化了 context 的所有方法。</p>
<p>再移步到 response.js、request.js,这两个 js 是对 context.response、context.request 方法的实现。</p>
<p>over!!!</p>
</div>
<footer class="clearfix">
<div class="categories">
<i class="fa fa-folder"></i>
<a href="/categories/前端/">前端</a>
</div>
<div class="tags">
<i class="fa fa-tags"></i>
<a href="/tags/Javascript/">#Javascript</a>
<a href="/tags/Node/">#Node</a>
<a href="/tags/前端/">#前端</a>
</div>
</footer>
</div>
</article>
<article class="post">
<div class="post-content">
<header>
<div class="meta">
<div class="icon">
<i class="fa fa-file"></i>
</div>
<time datetime="2016-02-23T02:29:15.000Z">2016-02-23</time>
</div>
<h1 class="title" data-role="articleTitle"><a href="/2016/02/23/学习 co/">学习 co</a></h1>
</header>
<div class="entry">
<p>co 是使用 ES6 generator 的必然会引用到的第三方库,它很好的解决了 yield 表达式返回值的问题,通过自动的不断调用 .next 使得函数向下执行。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> co = <span class="built_in">require</span>(<span class="string">'co'</span>);</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> * <span class="title">yieldFunc</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> i = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">var</span> a = <span class="keyword">yield</span> ++i;</span><br><span class="line"> <span class="keyword">var</span> a2 = <span class="keyword">yield</span> ++i;</span><br><span class="line"> <span class="keyword">return</span> {</span><br><span class="line"> <span class="number">1</span>: a,</span><br><span class="line"> <span class="number">2</span>: a2</span><br><span class="line"> };</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">co(<span class="function"><span class="keyword">function</span>*(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> ret = <span class="keyword">yield</span> yieldFunc();</span><br><span class="line"> <span class="keyword">return</span> ret;</span><br><span class="line">}).then(<span class="function"><span class="keyword">function</span>(<span class="params">ret</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(ret);</span><br><span class="line">});</span><br></pre></td></tr></table></figure>
<p>上面是一个 co 的使用范例。它接受一个 generator 函数作为参数,返回一个 Promise 对象,将 generator 函数的执行结果作为 resolve 的参数,通过调用 then 方法,将结果打印到控制台。</p>
<p>co 的源码很短,不过 200 来行(注释计算在内了),如果我们只按照上面的例子调用 co,co 可以简化为如下代码<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = simpleCo;</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">simpleCo</span>(<span class="params">gen</span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> ctx = <span class="keyword">this</span>;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span>(<span class="params">resolve, reject</span>) </span>{</span><br><span class="line"> gen = gen.call(ctx);</span><br><span class="line"> fulNext();</span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">fulNext</span>(<span class="params">res</span>) </span>{</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">var</span> ret = gen.next(res);</span><br><span class="line"> <span class="keyword">if</span> (!ret.done) {</span><br><span class="line"> fulNext(ret.value);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> resolve(ret.value);</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">catch</span> ( e ) {</span><br><span class="line"> reject(e);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>20 行足矣,源码见 <a href="https://github.com/dnxbf321/simple-co" target="_blank" rel="external">github</a>。</p>
</div>
<footer class="clearfix">
<div class="categories">
<i class="fa fa-folder"></i>
<a href="/categories/前端/">前端</a>
</div>
<div class="tags">
<i class="fa fa-tags"></i>
<a href="/tags/Javascript/">#Javascript</a>
<a href="/tags/Node/">#Node</a>
<a href="/tags/前端/">#前端</a>
</div>
</footer>
</div>
</article>
<article class="post">
<div class="post-content">
<header>
<div class="meta">
<div class="icon">
<i class="fa fa-file"></i>
</div>
<time datetime="2016-01-05T02:00:20.000Z">2016-01-05</time>
</div>
<h1 class="title" data-role="articleTitle"><a href="/2016/01/05/ECMAScript 2015 (ES6) 概览/">ECMAScript 2015 (ES6) 概览</a></h1>
</header>
<div class="entry">
<h2 id="Sublime_Text_中运行_ES6">Sublime Text 中运行 ES6</h2><ol>
<li><p>安装最新版的 node</p>
</li>
<li><p>配置新的 build 系统</p>
<ol>
<li><p>打开 Tools -> Build System -> New Build System…</p>
</li>
<li><p>编辑如下:{ “cmd”: [“/usr/local/bin/node”, “–use-strict”, “–harmony_destructuring”, “$file”], “selector”: “source.js”}</p>
</li>
<li><p>保存成 ES6.sublime-build 到默认路径</p>
</li>
</ol>
</li>
<li><p>测试</p>
<ol>
<li><p>编辑 test.js</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> [foo, bar] = [<span class="number">1</span>, <span class="number">2</span>];</span><br><span class="line"><span class="built_in">console</span>.log(foo, bar);</span><br></pre></td></tr></table></figure>
</li>
<li><p>运行: Cmd + B</p>
</li>
<li><p>控制台输出:1 2</p>
</li>
</ol>
</li>
</ol>
<h2 id="ECMAScript_2015_(ES6)_简介">ECMAScript 2015 (ES6) 简介</h2><p>ECMAScript 6 是 JavaScript 语言的新一代标准,它于2000年开始制定,历经15年,终于在2015年6月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。</p>
<h2 id="let_和_const">let 和 const</h2><p>let 声明局部变量,为Javascript 新增了块级作用域,不允许在同一作用域内,重复声明同一个变量</p>
<p>const 声明常量,必须初始化,一旦声明,不许改变</p>
<p>let 和 const 变量声明不提升</p>
<h2 id="变量的解构赋值">变量的解构赋值</h2><p>ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。</p>
<p>解构赋值便于我们一次性声明多个变量,方便提取函数返回值、JSON 数据,允许设置默认值。</p>
<h3 id="数组的解构赋值_模式匹配">数组的解构赋值 模式匹配</h3> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> [a, [b, c]] = [<span class="number">1</span>, [<span class="number">2</span>, <span class="number">3</span>]];</span><br></pre></td></tr></table></figure>
<p> 解构不成功,变量的值就等于 undefined</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> [a, b] = [<span class="number">1</span>];</span><br></pre></td></tr></table></figure>
<p> 不完全解构</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> [a, [b], c] = [<span class="number">1</span>, [<span class="number">2</span>, <span class="number">3</span>], <span class="number">4</span>];</span><br></pre></td></tr></table></figure>
<p> 解构赋值指定默认值</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> [a, b=<span class="number">2</span>] = [<span class="number">1</span>];</span><br></pre></td></tr></table></figure>
<h3 id="对象的解构赋值">对象的解构赋值</h3><p> 变量必须与属性同名<br> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> {a, b} = {a: <span class="number">1</span>, b: <span class="number">2</span>};</span><br></pre></td></tr></table></figure></p>
<p> 变量名与属性名不一致是,必须写成下面这样<br> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> {a: renameA, b} = {a: <span class="number">1</span>, b: <span class="number">2</span>};</span><br><span class="line"><span class="comment">// a 不被赋值,renameA = 1</span></span><br></pre></td></tr></table></figure></p>
<p> 解构用于嵌套结构。可把数据结构看成树,仅叶子被解析赋值,其他节点均仅为模式(undefined)。<br> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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> obj = {</span><br><span class="line"> p: [</span><br><span class="line"> <span class="string">"Hello"</span>,</span><br><span class="line"> { y: <span class="string">"World"</span> }</span><br><span class="line"> ]</span><br><span class="line">};</span><br><span class="line"><span class="keyword">var</span> { p: [x, { y }] } = obj;</span><br><span class="line"><span class="comment">// p 仅是模式,不会被赋值,p error undefined</span></span><br><span class="line"><span class="keyword">var</span> { p } = obj;</span><br><span class="line"><span class="comment">// p = ["hello, {y: "World"}"]</span></span><br></pre></td></tr></table></figure></p>
<h3 id="字符串的解构赋值">字符串的解构赋值</h3><p> 字符串被转换成一个类似数组的对象,类似 ‘hello’.split(‘’),按照对象解构赋值的规则进行</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> [a, b, c, d, e] = <span class="string">'hello'</span>;</span><br></pre></td></tr></table></figure>
<p> 字符串作为字符串对象进行解构赋值</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> {length: len} = <span class="string">'hello'</span>;</span><br></pre></td></tr></table></figure>
<h3 id="数值和布尔值的解构赋值">数值和布尔值的解构赋值</h3><p> 将数值和布尔值先转换成对象,再按照对象的规则进行</p>
<h3 id="null,_undefined_无法转换成对象,不能进行解构赋值">null, undefined 无法转换成对象,不能进行解构赋值</h3><h2 id="模板字符串">模板字符串</h2><p>用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> world = <span class="string">'world'</span>;</span><br><span class="line"></span><br><span class="line"><span class="string">`hello world`</span>;</span><br><span class="line"></span><br><span class="line"><span class="string">`</span><br><span class="line">hello world</span><br><span class="line">`</span></span><br><span class="line"></span><br><span class="line"><span class="string">`hello <span class="subst">${world}</span>`</span></span><br></pre></td></tr></table></figure>
<p> 模板字符串中嵌入变量,需要将变量名写在${}之中。大括号内部可以放入任意的JavaScript表达式,可以进行运算,以及引用对象属性。</p>
<h2 id="标签模板">标签模板</h2><p>模板字符串紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。常被用来过滤 HTML 字符串,防止恶意内容。另一个应用,就是多语言转换(国际化)。</p>
<h2 id="正则表达式">正则表达式</h2><p> u 修饰符,含义为 unicode 模式,用来正确处理四个字节的UTF-16编码。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">/^\uD83D/u.test(<span class="string">'\uD83D\uDC2A'</span>); <span class="comment">// false</span></span><br><span class="line">/^\uD83D/.test(<span class="string">'\uD83D\uDC2A'</span>); <span class="comment">// true</span></span><br><span class="line">/^.$/u.test(<span class="string">'我'</span>); <span class="comment">// true, . 也能匹配中文(两个字符)了</span></span><br></pre></td></tr></table></figure>
<p> y 修饰符,也叫『粘连』(sticky)修饰符。</p>
<p> y修饰符的作用与g修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始。不同之处在于,g修饰符只要剩余位置中存在匹配就可,而y修饰符确保匹配必须从剩余的第一个位置开始,这也就是“粘连”的涵义。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> str = <span class="string">'aaa_aa_a'</span>;</span><br><span class="line"><span class="keyword">var</span> re = <span class="regexp">/a+/y</span>;</span><br><span class="line">re.exec(str); <span class="comment">// ["aaa"]</span></span><br><span class="line">re.exec(str); <span class="comment">// null</span></span><br></pre></td></tr></table></figure>
<p> 目前,y、u 修饰符都还不支持</p>
<h2 id="数值扩展">数值扩展</h2><table>
<thead>
<tr>
<th>进制</th>
<th>前缀</th>
</tr>
</thead>
<tbody>
<tr>
<td> 二进制</td>
<td>0b</td>
</tr>
<tr>
<td> 八进制</td>
<td>0o</td>
</tr>
<tr>
<td> 十六进制</td>
<td>0x</td>
</tr>
</tbody>
</table>
<p> Number(0x15) 转换成十进制,非数字转换为数值</p>
<p> Number.isFinite 判断非无穷</p>
<p> Number.isNaN 判断非数值</p>
<p> Number.parseInt 转整数</p>
<p> Number.parseFloat 转浮点数</p>
<p> Number.isInteger 判断是否是整数</p>
<p> window.isFinite 对参数先调用 Number()</p>
<p> window.isNaN</p>
<p> Math.trunc 返回数值的整数部分</p>
<p> Math.sign 判断数值是正数、负数、还是零,结果: 1、-1、0、-0、NaN</p>
<h2 id="Iterator(遍历器)">Iterator(遍历器)</h2><p> 提供统一的访问机制遍历数据集合的成员。供 for…of 使用。</p>
<p> map|set|array</p>
<pre><code>.<span class="function"><span class="title">keys</span><span class="params">()</span></span>:返回一个键名的遍历器
.<span class="function"><span class="title">values</span><span class="params">()</span></span>:返回一个键值的遍历器
.<span class="function"><span class="title">entries</span><span class="params">()</span></span>:返回一个键值对的遍历器
</code></pre> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="keyword">let</span> [index, value] <span class="keyword">of</span> [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>].entries()) {</span><br><span class="line"> index; <span class="comment">// 0, 1, 2</span></span><br><span class="line"> value; <span class="comment">// 1, 2, 3</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="数组扩展">数组扩展</h2><p> Array.from 将类似数组的对象和可遍历的对象转换成真正的数组</p>
<p> Array.of 将一组值转换为数组</p>
<p> array.copyWithin(target, start, end) 将 start 位到 end 前一位复制到 target 位开始的位置</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>].copyWithin(<span class="number">0</span>, <span class="number">2</span>, -<span class="number">1</span>);</span><br><span class="line"><span class="comment">// [3, 4, 3, 4, 5]</span></span><br></pre></td></tr></table></figure>
<p> array.find((item)=>{return true}) 遍历数组,找出第一个符合条件(回调函数返回 true)的值,将该值返回</p>
<p> array.findIndex 同上,返回该值的位置,找不到符合条件的返回 -1</p>
<p> array.fill(value, start, end) 往原数组的 start 位置到 end 前一个位置填充 value</p>
<h2 id="函数扩展">函数扩展</h2><p> 参数默认值。参数值为 undefined 时,赋予默认值。在尾参数上定义默认值,否则该参数是没法省略的。</p>
<p> 指定了默认值以后,函数的length属性,将返回没有指定默认值的参数个数。</p>
<p> 可用于指定某一参数不能被省略,或表明这个参数可以省略</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">throwMissing</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">'missing'</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">f</span>(<span class="params">a=throwMissing(</span>), <span class="title">b</span>=2, <span class="title">c</span>=3) </span>{</span><br><span class="line">}</span><br><span class="line">f(<span class="number">1</span>); <span class="comment">// a=1, b=2, c=3</span></span><br><span class="line">f(<span class="number">1</span>, <span class="literal">undefined</span>, <span class="number">4</span>); <span class="comment">// a=1, b=2, c=4</span></span><br><span class="line">f.length; <span class="comment">// 0</span></span><br></pre></td></tr></table></figure>
<p> rest 参数。获取函数多余的参数。ES6 严格模式不能使用 arguments。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">f</span>(<span class="params">head, ...arg</span>) </span>{}</span><br><span class="line">f(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>); <span class="comment">//head=1, arg=[2, 3]</span></span><br></pre></td></tr></table></figure>
<p> 扩展运算符(…arrayName)。将数组转换为逗号分隔的参数序列。主要用于函数调用。</p>
<p> 应用:</p>
<ol>
<li><p>代替apply</p>
</li>
<li><p>合并数组</p>
</li>
<li><p>与解构赋值组合生成数组</p>
</li>
<li><p>得到正确的字符串长度</p>
</li>
<li><p>将实现了Iterator接口的对象转换成数组</p>
</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">push</span>(<span class="params">array, ...items</span>) </span>{</span><br><span class="line"> array.push(...items); <span class="comment">// [1, 2, 3]</span></span><br><span class="line"> array.push.apply(array, items); <span class="comment">// bad case</span></span><br><span class="line">}</span><br><span class="line">push([], <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>);</span><br><span class="line"></span><br><span class="line">[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, ...[<span class="number">4</span>, <span class="number">5</span>]]; <span class="comment">// [1, 2, 3, 4, 5]</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> [a, ...rest] = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>]; <span class="comment">//a=1, rest=[2, 3, 4]</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> str = <span class="string">'我shi'</span>;</span><br><span class="line">[...str].length; <span class="comment">// 5</span></span><br></pre></td></tr></table></figure>
<p> 箭头函数 ()=>{} 语法糖</p>
<h2 id="对象扩展">对象扩展</h2><p> Object.is 同值相等,基本与 === 一致,但是 +0 不等于 -0, NaN 等于 NaN</p>
<p> Object.assign(target, source, source2) 将 source、source2 对象的自身属性复制到 target 对象,不可枚举属性和继承的属性不被拷贝。对于嵌套的对象,此方法执行的是替换,而非添加。应用:</p>
<pre><code>-<span class="ruby"> 为对象添加属性和方法
</span>
-<span class="ruby"> 克隆对象
</span>
-<span class="ruby"> 合并对象
</span>
-<span class="ruby"> 为对象属性指定默认值</span>
</code></pre><h2 id="Set_和_WeakSet">Set 和 WeakSet</h2><p> 它类似于数组,但是成员的值都是唯一的,没有重复的值。WeakSet 的成员只能是对象。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> <span class="built_in">Set</span>([<span class="number">1</span>, <span class="number">2</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">4</span>])</span><br></pre></td></tr></table></figure>
<p> set.size set成员个数</p>
<p> set.add 添加成员</p>
<p> set.delete 删除成员</p>
<p> set.has 检查是否拥有某值</p>
<p> set.clear 清空set</p>
<h2 id="Map_和_WeakMap">Map 和 WeakMap</h2><p> 类似于 Object,但是 Map 的键不局限于字符串。WeakMap 的键只能是对象,NaN 除外。</p>
<p> map.size 成员个数</p>
<p> map.set(key, value) 添加成员</p>
<p> map.get(key) 返回指定 key 的成员的值,找不到则返回 undefined</p>
<p> map.has 检查数据中是否含有某值</p>
<p> map.delete 删除指定键值成员,成功返回 true,失败返回 false</p>
<p> map.clear 清空map</p>
<h2 id="WeakSet_和_WeakMap">WeakSet 和 WeakMap</h2><p> 没有 size 属性,没有遍历操作,无法清空。</p>
<p> 典型应用是,一个对应DOM元素的WeakMap结构,当某个DOM元素被清除,其所对应的WeakMap记录就会自动被移除。基本上,WeakMap的专用场合就是,它的键所对应的对象,可能会在将来消失。WeakMap结构有助于防止内存泄漏。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> wm = <span class="keyword">new</span> <span class="built_in">WeakMap</span>();</span><br><span class="line"><span class="keyword">var</span> element = <span class="built_in">document</span>.querySelector(<span class="string">".element"</span>);</span><br><span class="line"></span><br><span class="line">wm.set(element, <span class="string">"Original"</span>);</span><br><span class="line">wm.get(element) <span class="comment">// "Original"</span></span><br><span class="line"></span><br><span class="line">element.parentNode.removeChild(element);</span><br><span class="line">element = <span class="literal">null</span>;</span><br><span class="line">wm.get(element) <span class="comment">// undefined</span></span><br></pre></td></tr></table></figure>
<h2 id="Generator_函数">Generator 函数</h2> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span>* <span class="title">f</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">yield</span> <span class="string">'1'</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="keyword">yield</span> <span class="string">'2'</span>;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="number">2</span>);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> it = f();</span><br><span class="line">it.next(); <span class="comment">// 执行 yield '1',等到 next 命令再向下执行</span></span><br><span class="line">it.next(); <span class="comment">// 1</span></span><br><span class="line">it.next(); <span class="comment">// 2</span></span><br></pre></td></tr></table></figure>
<p> 形式上,function 与方法名中间有(*)号,函数内部用 yield(产出),定义不同内部状态。yield 只能出现在 generator 函数中。</p>
<p> 执行 generator 函数会返回一个遍历器,不断的执行 next,遍历函数的每一个状态。</p>
<p> yield 语句本身没有返回值,通过在 next 带上一个参数,设置上一个 yield 的返回值。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span>* <span class="title">f</span>(<span class="params">x=1</span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> y = <span class="keyword">yield</span> (x + <span class="number">1</span>);</span><br><span class="line"> <span class="keyword">var</span> z = <span class="keyword">yield</span> (x + y);</span><br><span class="line"> <span class="keyword">return</span> x + y + z;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> it = f();</span><br><span class="line">it.next(); <span class="comment">// x=1, y=undefined, z=undefined</span></span><br><span class="line">it.next(<span class="number">4</span>); <span class="comment">// x=1, y=4, z=undefined</span></span><br><span class="line">it.next(<span class="number">10</span>); <span class="comment">// x=1, y=4, z=10</span></span><br></pre></td></tr></table></figure>
<p> for … of … 可代替 next</p>
<p>如果在 generator 函数中再调用其他 generator 函数,需要使用 yield * 语句</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">function * bar() { yield 1; } function * foo() { yield * bar(); }</span><br></pre></td></tr></table></figure>
<h2 id="Promise">Promise</h2><p> 一个对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的API,可供进一步处理。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> p = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span>(<span class="params">resolve, reject</span>) </span>{</span><br><span class="line"> setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> resolve(<span class="string">'a'</span>);</span><br><span class="line"> }, <span class="number">2000</span>);</span><br><span class="line">});</span><br><span class="line">p.then(<span class="function"><span class="keyword">function</span>(<span class="params">result</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(result);</span><br><span class="line">});</span><br><span class="line"><span class="comment">// 2秒后输出 a</span></span><br></pre></td></tr></table></figure>
<p> promise.then 为 promise 实例添加状态改变时的回调函数,第一个参数为 resolved 的回调,第二个参数是 rejected 的回调</p>
<p> promise.catch 指定发生错误时的回调函数</p>
<p> Promise.race 将多个 promise 实例包装成一个新实例,只要一个实例的状态改变了,新实例的状态就跟着改变了,传递给回调函数的值为率性改变状态示例的返回值</p>
<p> Promise.all 将多个 Promise 实例包装秤一个新实例,所有的实例状态改变了,新实例的状态才会改变,新实例的状态由各个实例的最终状态执行『且』运算得到,传递给回调函数的值为每个实例结果组成的数组</p>
<p> Promise.resolve 返回一个状态为 resolved 的实例</p>
<p> Promise.reject 返回一个状态为 rejected 的实例</p>
<h2 id="Class">Class</h2><p> ECMAScript 5 构造函数的语法糖。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span> </span>{</span><br><span class="line"> constructor() {</span><br><span class="line"> <span class="keyword">this</span>.a = <span class="string">'a'</span>;</span><br><span class="line"> }</span><br><span class="line"> sayIt() {</span><br><span class="line"> alert(<span class="keyword">this</span>.a);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="comment">// ES 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="keyword">this</span>.a = <span class="string">'a'</span>;</span><br><span class="line">}</span><br><span class="line">A.prototype.sayIt = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> alert(<span class="keyword">this</span>.a);</span><br><span class="line">};</span><br></pre></td></tr></table></figure>
<p> Class 继承</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">B</span> <span class="keyword">extends</span> <span class="title">A</span> </span>{</span><br><span class="line"> constructor() {</span><br><span class="line"> <span class="keyword">super</span>();</span><br><span class="line"> <span class="keyword">this</span>.a = <span class="string">'b'</span>;</span><br><span class="line"> }</span><br><span class="line"> sayIt() {</span><br><span class="line"> <span class="keyword">super</span>.sayIt();</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> b = <span class="keyword">new</span> B();</span><br><span class="line">b.sayIt();</span><br></pre></td></tr></table></figure>
<p> super关键字指向父类</p>
<p> static 关键字,表示该方法不会被实例继承,而是直接通过类来调用,被称为静态方法。静态方法会被继承。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span>() </span>{</span><br><span class="line"> constructor() {}</span><br><span class="line"> static sayHi() {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'hi'</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line">A.sayHi();</span><br></pre></td></tr></table></figure>
<p> 静态属性。class 内部只有静态方法,没有静态属性。<br> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span>() </span>{}</span><br><span class="line">A.hi = <span class="string">'hi'</span>;</span><br></pre></td></tr></table></figure></p>
<h2 id="模块">模块</h2><p> 通过export命令显式指定输出的代码,输入时采用import静态命令</p>
<h3 id="export_命令">export 命令</h3> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// jackson.js</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">var</span> firstName = <span class="string">'Michael'</span>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">var</span> lastName = <span class="string">'Jackson'</span>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">var</span> year = <span class="number">1958</span>;</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> firstName = <span class="string">'Michael'</span>;</span><br><span class="line"><span class="keyword">var</span> lastName = <span class="string">'Jackson'</span>;</span><br><span class="line"><span class="keyword">var</span> year = <span class="number">1958</span>;</span><br><span class="line"><span class="keyword">export</span> {firstName, lastName, year};</span><br></pre></td></tr></table></figure>
<p> as 重命名对外接口名称<br> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> firstName = <span class="string">'Michael'</span>;</span><br><span class="line"><span class="keyword">var</span> lastName = <span class="string">'Jackson'</span>;</span><br><span class="line"><span class="keyword">var</span> year = <span class="number">1958</span>;</span><br><span class="line"><span class="keyword">export</span> {firstName <span class="keyword">as</span> fn, lastName <span class="keyword">as</span> ln, year <span class="keyword">as</span> y};</span><br></pre></td></tr></table></figure></p>
<p> export default 为模块指定默认输出<br> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// jackson2.js</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> {firstName: <span class="string">'Mickael'</span>, lastName: <span class="string">'Jackson'</span>, year: <span class="number">1958</span>};</span><br></pre></td></tr></table></figure></p>
<h3 id="import_命令">import 命令</h3><p> 引入具体的值<br> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> {firstName, lastName, year} <span class="keyword">from</span> <span class="string">'./jackson'</span>;</span><br></pre></td></tr></table></figure></p>
<p> 全部引入<br> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> * <span class="keyword">as</span> jackson <span class="keyword">from</span> <span class="string">'./jackson'</span>;</span><br></pre></td></tr></table></figure></p>
<p> 引入使用 export default 的模块<br> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> jackson <span class="keyword">from</span> <span class="string">'./jackson2'</span>;</span><br></pre></td></tr></table></figure></p>
</div>
<footer class="clearfix">
<div class="categories">
<i class="fa fa-folder"></i>
<a href="/categories/前端/">前端</a>
</div>
<div class="tags">
<i class="fa fa-tags"></i>
<a href="/tags/Javascript/">#Javascript</a>
<a href="/tags/前端/">#前端</a>
</div>
</footer>
</div>
</article>
<nav id="pagination">
<a href="/page/2/" class="next">下一页 <i class="fa fa-chevron-right"></i></a>
</nav>
<script>
(function (disqus_shortname) {
window.addEventListener('DOMContentLoaded', function () {
var dsq = document.createElement('script');
dsq.type = 'text/javascript';
dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/count.js';
document.getElementsByTagName('head')[0].appendChild(dsq);
}, false);
}('dnxbf321'));
</script>
</div>
</div>
</div>
<footer id="footer">
<div class="center">
© 2016
Jason Tung
.
Blog generated by <a href="http://hexo.io">hexo</a>
</div>
</footer>
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
<script src="/js/header-animate.js"></script>
<script src="/js/title-animate.js"></script>
<script src="/bower_components/jquery_lazyload/jquery.lazyload.js"></script>
<script>
$('img.lazy').lazyload();
</script>
<script src="/bower_components/fancybox/source/jquery.fancybox.pack.js"></script>
<script>
$('.fancybox').fancybox();
</script>
</body>
</html>