-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
604 lines (456 loc) · 74 KB
/
atom.xml
File metadata and controls
604 lines (456 loc) · 74 KB
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
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>0 to 1</title>
<subtitle>Talk is cheap, Show me the code.</subtitle>
<link href="/atom.xml" rel="self"/>
<link href="http://lvu.me/"/>
<updated>2016-09-18T15:03:33.000Z</updated>
<id>http://lvu.me/</id>
<author>
<name>gpia</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>努力向上</title>
<link href="http://lvu.me/2016/09/18/%E5%8A%AA%E5%8A%9B%E5%90%91%E4%B8%8A/"/>
<id>http://lvu.me/2016/09/18/努力向上/</id>
<published>2016-09-18T14:54:36.000Z</published>
<updated>2016-09-18T15:03:33.000Z</updated>
<content type="html"><![CDATA[<p>对于自己一直要求不严格,自认为的聪明也是荒废了。有人说,男人就该对自己狠一点;有人说,你一事无成,却能安然入睡。之前听过也就只是听过,总是很难改变自己,习惯了安逸。</p>
<p>可是现在我有了爱的人,我绝不能再这么慢悠悠的了。我之前一直觉得,只要我按照目前的计划,前进,就可以了,但是现在看来,我还是把生活想得简单了,把自己看得太高了。</p>
<p>目标还是越清晰越好,有一个明确的奋斗方向,什么时候达到什么阶段,什么时候取得什么东西,都应该更加细致,并严格去执行。</p>
<p>从今天起,我要开始一个新的阶段,期待坚持下去的我,期待更好的我。</p>
<p>这是我的作战宣言。</p>
]]></content>
<summary type="html">
<p>对于自己一直要求不严格,自认为的聪明也是荒废了。有人说,男人就该对自己狠一点;有人说,你一事无成,却能安然入睡。之前听过也就只是听过,总是很难改变自己,习惯了安逸。</p>
<p>可是现在我有了爱的人,我绝不能再这么慢悠悠的了。我之前一直觉得,只要我按照目前的计划,前进,就
</summary>
<category term="随笔" scheme="http://lvu.me/categories/%E9%9A%8F%E7%AC%94/"/>
<category term="随笔" scheme="http://lvu.me/tags/%E9%9A%8F%E7%AC%94/"/>
</entry>
<entry>
<title>JavaScript同源策略和跨域</title>
<link href="http://lvu.me/2016/08/16/JavaScript%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5%E5%92%8C%E8%B7%A8%E5%9F%9F/"/>
<id>http://lvu.me/2016/08/16/JavaScript同源策略和跨域/</id>
<published>2016-08-16T15:52:01.000Z</published>
<updated>2016-09-18T14:46:15.000Z</updated>
<content type="html"><![CDATA[<p>同源策略是对JavaScript代码能够操作哪些Web内容的一条完整的安全限制。当Web页面使用多个iframe元素或者打开其他浏览器窗口的时候,这一策略通常就会发生作用。具体来说,脚本只能读取和所属文档来源相同的窗口和文档的属性。</p>
<p>文档的来源包括:协议,主机,端口。三者有任何一个不同,即为不同来源。需要说明的一点是,文档中的脚本本身的来源和同源策略并不相关,这一点非常重要。例如,一个来自主机A的脚本被包含到(使用script标签的src属性)宿主B的一个页面中,那么,这个脚本的来源是主机B,简单的说,就是脚本本身来自哪里不重要,重要的是脚本被包含在哪个文档里。<br><a id="more"></a><br>实际上,同源策略并非应用于不同源的窗口的所有对象的所有属性,不过他应用到了其中的大部分属性,尤其是Document对象的几乎所有属性。此外,同源策略还会阻止XMLHttpRequest对不同文档来源的请求。</p>
<p>不同来源文档之间的相互访问称为跨域(访问),同源策略能够阻止跨域访问带来的安全问题。</p>
<p>对于使用多个子域的大站点来说,同源策略就显得有点过于严格了,比如home.example.com的文档里的脚本要合法地访问developer.example.com载入的文档的属性。这种情况下,可以通过文档中的脚本设置document的domain属性,使得两个子域的文档的domain是同一个值,这样,这两个窗口就可以不受同源策略的限制了。<br>当然,domain的值不能是任意值,它只能是当前文档来源域的前缀或者他本身,另外domain中必须有一个点号,不能设置为“com”这样的顶级域名,比如home.example.com可以设置domain为example.com。对于home.example.com和developer.example.com,只要将它们的文档domain设置为example.com就可以进行跨域操作了。</p>
<p>对于XMLHttpRequest的跨域请求,可以通过跨域资源共享(Cross-Origin Resource Sharing,即CORS)来实现。具体是在跨域http请求头部增加Origin属性,对应的响应头部增加Access-Control-Allow-Origin。<br>当然,对于跨域请求,可以借助JSONP技术,具体即借助script标签的src属性可以加载不同来源的脚本来实现。<br>另外,通过跨文档信息(cross-document messaging)技术,可以在不同文档的脚本之间传递消息,而不用管脚本的来源是否不同。调动window对象上的postMessage()方法,可以一步传递消息时间(可以用onmessage时间处理程序来处理它)到窗口的文档里。</p>
]]></content>
<summary type="html">
<p>同源策略是对JavaScript代码能够操作哪些Web内容的一条完整的安全限制。当Web页面使用多个iframe元素或者打开其他浏览器窗口的时候,这一策略通常就会发生作用。具体来说,脚本只能读取和所属文档来源相同的窗口和文档的属性。</p>
<p>文档的来源包括:协议,主机,端口。三者有任何一个不同,即为不同来源。需要说明的一点是,文档中的脚本本身的来源和同源策略并不相关,这一点非常重要。例如,一个来自主机A的脚本被包含到(使用script标签的src属性)宿主B的一个页面中,那么,这个脚本的来源是主机B,简单的说,就是脚本本身来自哪里不重要,重要的是脚本被包含在哪个文档里。<br>
</summary>
<category term="JavaScript" scheme="http://lvu.me/categories/JavaScript/"/>
<category term="同源策略" scheme="http://lvu.me/categories/JavaScript/%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5/"/>
<category term="javascript" scheme="http://lvu.me/tags/javascript/"/>
<category term="同源策略" scheme="http://lvu.me/tags/%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5/"/>
<category term="跨域" scheme="http://lvu.me/tags/%E8%B7%A8%E5%9F%9F/"/>
</entry>
<entry>
<title>JavaScript函数节流</title>
<link href="http://lvu.me/2016/08/13/JavaScript%E5%87%BD%E6%95%B0%E8%8A%82%E6%B5%81/"/>
<id>http://lvu.me/2016/08/13/JavaScript函数节流/</id>
<published>2016-08-13T15:50:48.000Z</published>
<updated>2016-09-12T16:08:57.000Z</updated>
<content type="html"><![CDATA[<p>JavaScript中,经常有一种场景,比如我们要在窗口大小变化的时候,同步调整一下图形的大小,或者在文档滚动的时候判断是否加载数据,简单地说,我们可以直接绑定事件,如下:<br><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">f</span>(<span class="params"></span>) </span>{</div><div class="line"> <span class="comment">//do something</span></div><div class="line">}</div><div class="line">$(<span class="built_in">window</span>).resize(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> f();</div><div class="line">});</div></pre></td></tr></table></figure></p>
<p>但是,上述代码有可能有问题。<br><a id="more"></a><br>由于在每次窗口变化的时候,可能会多次触发resize事件,导致f被执行多次,尤其是当处理的方法比较复杂,执行效率较低,或者我们想在每次窗口变化的时候,只执行一次f,这时候就需要进行“函数节流”了,我们让多次resize“合并”成一次resize,即使用一种方式,让每次窗口大小变化都只触发一次resize(实际上是很多次,可打印log验证),上代码:<br><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//说明:这是一个节流方法,接收第一个参数,是要实际执行的函数,delay是一个延迟时间,即每多少时间作为一个节流周期</span></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">throttle</span>(<span class="params">fn, delay</span>) </span>{</div><div class="line"> <span class="keyword">var</span> timer = <span class="literal">null</span>;</div><div class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> <span class="keyword">var</span> context = <span class="keyword">this</span>, args = <span class="built_in">arguments</span>;</div><div class="line"> clearTimeout(timer);</div><div class="line"> timer = setTimeout(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> fn.apply(context, args);</div><div class="line"> }, delay);</div><div class="line"> };</div><div class="line"> };</div></pre></td></tr></table></figure></p>
<p>有了上面的节流函数,我们的resize事件可以优化成:<br><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$(<span class="built_in">window</span>).resize(throttle(f, <span class="number">50</span>));</div></pre></td></tr></table></figure></p>
]]></content>
<summary type="html">
<p>JavaScript中,经常有一种场景,比如我们要在窗口大小变化的时候,同步调整一下图形的大小,或者在文档滚动的时候判断是否加载数据,简单地说,我们可以直接绑定事件,如下:<br><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">f</span>(<span class="params"></span>) </span>&#123;</div><div class="line"> <span class="comment">//do something</span></div><div class="line">&#125;</div><div class="line">$(<span class="built_in">window</span>).resize(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</div><div class="line"> f();</div><div class="line">&#125;);</div></pre></td></tr></table></figure></p>
<p>但是,上述代码有可能有问题。<br>
</summary>
<category term="JavaScript" scheme="http://lvu.me/categories/JavaScript/"/>
<category term="技巧" scheme="http://lvu.me/categories/JavaScript/%E6%8A%80%E5%B7%A7/"/>
<category term="javascript" scheme="http://lvu.me/tags/javascript/"/>
<category term="函数节流" scheme="http://lvu.me/tags/%E5%87%BD%E6%95%B0%E8%8A%82%E6%B5%81/"/>
</entry>
<entry>
<title>JavaScript中正则表达式的一些应用</title>
<link href="http://lvu.me/2016/08/10/JavaScript%E4%B8%AD%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E7%9A%84%E4%B8%80%E4%BA%9B%E5%BA%94%E7%94%A8/"/>
<id>http://lvu.me/2016/08/10/JavaScript中正则表达式的一些应用/</id>
<published>2016-08-10T14:51:34.000Z</published>
<updated>2016-08-13T16:24:21.000Z</updated>
<content type="html"><![CDATA[<p>前面讲了正则表达式的基础知识<a href="/2016/08/07/正则表达式入门/">正则表达式入门</a>,以及<a href="/2016/08/07/JavaScript对正则表达式的支持/">JavaScript对正则表达的支持</a>之后,现在来看下正则表达式的应用实例。</p>
<ol>
<li><p>对数字进行千分位分隔</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//说明:对于数字中的任何一位,如果其后面有3,6,9,... 位数字,那么该位后面就应该有一个,</span></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">numberFormat</span>(<span class="params">num</span>) </span>{</div><div class="line"> <span class="keyword">return</span> <span class="built_in">String</span>(num).replace(<span class="regexp">/\d(?=(\d{3})+$)/g</span>, <span class="string">'$&,'</span>);</div><div class="line">}</div><div class="line"><span class="built_in">console</span>.log(numberFormat(<span class="number">1234567</span>)); <span class="comment">// 1,234,567</span></div></pre></td></tr></table></figure>
</li>
<li><p>获取url参数</p>
<a id="more"></a>
<figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//说明:url查询字符串以 ? 开头,参数以 & 分隔,参数组如 key=value</span></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">getUrlParam</span>(<span class="params">name</span>) </span>{</div><div class="line"> <span class="keyword">var</span> str = location.search,</div><div class="line"> reg = <span class="keyword">new</span> <span class="built_in">RegExp</span>(<span class="string">'[?&]'</span> + name + <span class="string">'='</span> + <span class="string">'([^&]*)'</span>),</div><div class="line"> result;</div><div class="line"> result = reg.exec(str);</div><div class="line"> <span class="keyword">return</span> result ? <span class="built_in">decodeURIComponent</span>(result[<span class="number">1</span>]) : <span class="literal">undefined</span>;</div><div class="line">}</div></pre></td></tr></table></figure>
</li>
<li><p>获取cookie值</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//说明:cookie 以 '; ' 分隔</span></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">getCookie</span>(<span class="params">name</span>) </span>{</div><div class="line"> <span class="keyword">var</span> reg = <span class="keyword">new</span> <span class="built_in">RegExp</span>(<span class="string">'(?:^| )'</span> + name + <span class="string">'=([^;]*)(;|$)'</span>),</div><div class="line"> result = reg.exec(<span class="built_in">document</span>.cookie);</div><div class="line"> <span class="keyword">return</span> result ? <span class="built_in">decodeURIComponent</span>(result[<span class="number">1</span>]) : <span class="literal">undefined</span>;</div><div class="line">}</div></pre></td></tr></table></figure>
</li>
<li><p>日期格式化</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//说明:接收一个 date 类型,一个字符串 format,如:yyyy-MM-dd HH:mm:ss</span></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">dateFormat</span>(<span class="params">date, format</span>) </span>{</div><div class="line"> <span class="keyword">var</span> o = {</div><div class="line"> <span class="string">'y+'</span>: date.getFullYear(),</div><div class="line"> <span class="string">'M+'</span>: date.getMonth() + <span class="number">1</span>,</div><div class="line"> <span class="string">'d+'</span>: date.getDate(),</div><div class="line"> <span class="string">'H+'</span>: date.getHours(),</div><div class="line"> <span class="string">'h+'</span>: date.getHours() % <span class="number">12</span>,</div><div class="line"> <span class="string">'m+'</span>: date.getMinutes(),</div><div class="line"> <span class="string">'s+'</span>: date.getSeconds()</div><div class="line"> }, reg, tmp; </div><div class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> f <span class="keyword">in</span> o) {</div><div class="line"> reg = <span class="keyword">new</span> <span class="built_in">RegExp</span>(f, <span class="string">'g'</span>);</div><div class="line"> tmp = addPreZero(o[f]);</div><div class="line"> format = format.replace(reg, <span class="function"><span class="keyword">function</span> (<span class="params">m</span>) </span>{</div><div class="line"> <span class="keyword">return</span> tmp.slice(tmp.length - m.length);</div><div class="line"> });</div><div class="line"> } </div><div class="line"> <span class="keyword">return</span> format;</div><div class="line"> <span class="function"><span class="keyword">function</span> <span class="title">addPreZero</span>(<span class="params">n</span>) </span>{</div><div class="line"> <span class="keyword">return</span> <span class="built_in">String</span>(n < <span class="number">10</span> ? (<span class="string">'0'</span> + n) : n);</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure>
</li>
<li><p>IP4地址校验</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//说明:ipv4 四个部分以.分隔,每部分从0到255</span></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">isIpAddr</span>(<span class="params">ip</span>) </span>{</div><div class="line"> <span class="keyword">return</span> (((\d{<span class="number">1</span>,<span class="number">2</span>})|(<span class="number">1</span>\d{<span class="number">2</span>})|(<span class="number">2</span>[<span class="number">0</span><span class="number">-4</span>]\d)|(<span class="number">25</span>[<span class="number">0</span><span class="number">-5</span>]))\.){<span class="number">3</span>}((\d{<span class="number">1</span>,<span class="number">2</span>})|(<span class="number">1</span>\d{<span class="number">2</span>})|(<span class="number">2</span>[<span class="number">0</span><span class="number">-4</span>]\d)|(<span class="number">25</span>[<span class="number">0</span><span class="number">-5</span>])).test(ip);</div><div class="line">}</div></pre></td></tr></table></figure>
</li>
<li><p>11位手机号码校验</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//说明:现在手机号以 13,15,17,18 开头的11位数字</span></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">validPhoneNumber</span>(<span class="params">number</span>) </span>{</div><div class="line"> <span class="keyword">return</span> <span class="regexp">/^1[3578]\d{9}$/</span>.test(<span class="built_in">String</span>(number));</div><div class="line">}</div></pre></td></tr></table></figure>
</li>
</ol>
]]></content>
<summary type="html">
<p>前面讲了正则表达式的基础知识<a href="/2016/08/07/正则表达式入门/">正则表达式入门</a>,以及<a href="/2016/08/07/JavaScript对正则表达式的支持/">JavaScript对正则表达的支持</a>之后,现在来看下正则表达式的应用实例。</p>
<ol>
<li><p>对数字进行千分位分隔</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//说明:对于数字中的任何一位,如果其后面有3,6,9,... 位数字,那么该位后面就应该有一个,</span></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">numberFormat</span>(<span class="params">num</span>) </span>&#123;</div><div class="line"> <span class="keyword">return</span> <span class="built_in">String</span>(num).replace(<span class="regexp">/\d(?=(\d&#123;3&#125;)+$)/g</span>, <span class="string">'$&amp;,'</span>);</div><div class="line">&#125;</div><div class="line"><span class="built_in">console</span>.log(numberFormat(<span class="number">1234567</span>)); <span class="comment">// 1,234,567</span></div></pre></td></tr></table></figure>
</li>
<li><p>获取url参数</p>
</summary>
<category term="正则表达式" scheme="http://lvu.me/categories/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/"/>
<category term="应用" scheme="http://lvu.me/categories/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/%E5%BA%94%E7%94%A8/"/>
<category term="javascript" scheme="http://lvu.me/tags/javascript/"/>
<category term="正则表达式" scheme="http://lvu.me/tags/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/"/>
</entry>
<entry>
<title>JavaScript对正则表达式的支持</title>
<link href="http://lvu.me/2016/08/07/JavaScript%E5%AF%B9%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E7%9A%84%E6%94%AF%E6%8C%81/"/>
<id>http://lvu.me/2016/08/07/JavaScript对正则表达式的支持/</id>
<published>2016-08-07T10:57:36.000Z</published>
<updated>2016-08-13T16:24:35.000Z</updated>
<content type="html"><![CDATA[<p>正则表达式是一种强大的工具,具体语法请看我的另一篇博客<a href="/2016/08/07/正则表达式入门/">正则表达式入门</a>,现在我们来看看正则表达式在JavaScript中的应用。<br>JavaScript对正则表达式的支持主要是由正则表达式类RegExp和字符串类String来提供的。</p>
<table>
<thead>
<tr>
<th>方法</th>
<th>所属类</th>
</tr>
</thead>
<tbody>
<tr>
<td>exec</td>
<td>RegExp</td>
</tr>
<tr>
<td>test</td>
<td>RegExp</td>
</tr>
<tr>
<td>match</td>
<td>String</td>
</tr>
<tr>
<td>replace</td>
<td>String</td>
</tr>
<tr>
<td>search</td>
<td>String</td>
</tr>
<tr>
<td>split</td>
<td>String</td>
</tr>
</tbody>
</table>
<a id="more"></a>
<p>在JavaScript中创建正则表达式对象,有两种方式:<br><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//方法1,使用正则表达式类RegExp</span></div><div class="line"><span class="comment">//参数1为模式,参数2为属性(可省略,默认不开启)</span></div><div class="line"><span class="comment">//i 忽略大小写,g 全局匹配,m 开启多行匹配</span></div><div class="line"><span class="keyword">var</span> reg = <span class="keyword">new</span> <span class="built_in">RegExp</span>(<span class="string">'[ab]c'</span>, <span class="string">'gim'</span>);</div><div class="line"></div><div class="line"><span class="comment">//方法2,使用正则表达式字面量</span></div><div class="line"><span class="comment">//使用/作为模式的开始和结束符号,后面紧接属性,意义同上</span></div><div class="line"><span class="keyword">var</span> reg = <span class="regexp">/[ab]c/gim</span>;</div></pre></td></tr></table></figure></p>
<p>有了正则表达式对象,我们可以直接使用正则表达式对象的方法 exec。<br>exec 方法接收一个字符串作为参数,对这个字符串进行正则匹配,如果没有匹配则返回null,否则返回一个结果数组。返回的数组第一项为整个模式的匹配值,后面依次为各个分组(子表达式)匹配的结果。如果没有开启全局匹配 g,它每次执行,总是返回第一个符合模式的匹配,否则它将每次返回下一个匹配,直到没有符合的匹配返回null,之后重新从第1个匹配开始返回。所以可以通过循环找到一个字符串中所有的匹配。<br>顺便说一句,这个结果数组,它上面还有两个属性,index:匹配的开始位置,input:原始文本,感兴趣的自行查看,我们先忽略这个。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> str = <span class="string">'so wo know the number is 100, and total is 666.'</span>;</div><div class="line"><span class="keyword">var</span> reg = <span class="regexp">/(\w*)\s*is\s*(\d+)/</span>; </div><div class="line"><span class="keyword">var</span> result = reg.exec(str); <span class="comment">//result: ["number is 100", "number", "100"]</span></div><div class="line">result = reg.exec(str); <span class="comment">//再次执行,result依然为 ["number is 100", "number", "100"]</span></div><div class="line"></div><div class="line"><span class="comment">//开启全局匹配</span></div><div class="line">reg = <span class="regexp">/(\w*)\s*is\s*(\d+)/g</span>;</div><div class="line">result = reg.exec(str); <span class="comment">//result: ["number is 100", "number", "100"]</span></div><div class="line">result = reg.exec(str); <span class="comment">//接着执行,result: ["total is 666", "total", "666"]</span></div><div class="line">result = reg.exec(str); <span class="comment">//接着执行,result: null</span></div><div class="line">result = reg.exec(str); <span class="comment">//接着执行,重新开始匹配,result: ["number is 100", "number", "100"]</span></div></pre></td></tr></table></figure>
<p>下面,我们通过循环输出所有的匹配<br><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> str = <span class="string">'so wo know the number is 100, and total is 666.'</span>;</div><div class="line"><span class="keyword">var</span> reg = <span class="regexp">/(\w*)\s*is\s*(\d+)/g</span>; </div><div class="line"><span class="keyword">var</span> result, allResult = [];</div><div class="line"><span class="keyword">while</span> (result = reg.exec(str)) {</div><div class="line"> allResult.push(result); </div><div class="line">}</div><div class="line"><span class="built_in">console</span>.log(allResult); <span class="comment">// allResult: [["number is 100", "number", "100"], ["total is 666", "total", "666"]]</span></div></pre></td></tr></table></figure></p>
<p>至于正则表达式对象的 test 方法,用于测试一个字符串是否匹配这个模式,如果匹配则返回true,否则为false,此时是否全局匹配无影响。<br><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> str = <span class="string">'so wo know the number is 100, and total is 666.'</span>;</div><div class="line"><span class="keyword">var</span> reg = <span class="regexp">/(\w*)\s*is\s*(\d+)/</span>; </div><div class="line"><span class="keyword">var</span> reg1 = <span class="regexp">/not-found/</span>;</div><div class="line"><span class="built_in">console</span>.log(reg.test(str)); <span class="comment">//true</span></div><div class="line"><span class="built_in">console</span>.log(reg1.test(str)); <span class="comment">//false</span></div></pre></td></tr></table></figure></p>
<p>接下来看下字符串中支持正则表达式的相关方法,以下这些方法都可以接受一个普通的字符串作为参数,这里不谈。</p>
<p>字符串的 match 方法可以接收一个正则表达式作为参数,在字符串内检索与正则相匹配的内容。当正则表达式没有g标志时,返回结果和 RegExp 的 exec 返回结果相同,即如果找到,则返回一个数组,数组第0项为该模式的匹配文本,后面的项依次是子表达式匹配的内容,该返回数组还有 input 和 index属性(先忽略这个);当正则表达式有g标志时,返回结果则不同,此时,返回的也是一个数组,但是里面的每一项是该模式的所有匹配文本,不含子表达式信息。如果不匹配,返回null。<br><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> str = <span class="string">'so wo know the number is 100, and total is 666.'</span>;</div><div class="line"><span class="keyword">var</span> reg = <span class="regexp">/(\w*)\s*is\s*(\d+)/</span>; </div><div class="line"><span class="built_in">console</span>.log(str.match(reg)); <span class="comment">//["number is 100", "number", "100"]</span></div><div class="line"></div><div class="line">reg = <span class="regexp">/(\w*)\s*is\s*(\d+)/g</span>; <span class="comment">//加入全局标志</span></div><div class="line"><span class="built_in">console</span>.log(str.match(reg)); <span class="comment">//["number is 100", "total is 666"]</span></div></pre></td></tr></table></figure></p>
<p>字符串的 replace 方法也可以接收一个正则表达式作为第一个参数,第二个参数可以是字符串或者一个方法,当第二个参数是字符串的时候,可以使用一些特定符号:$n,n < 99,表示第n个子表达式对应的匹配,$&表示与正则表达式相匹配的文本,$`是位于匹配子串左侧的文本,$’是位于匹配子串右侧的文本,$$是插入$符号。<br>当第二个参数是方法的时候,其参数就是 match 时候结果数组依次传入,返回值作为本次匹配的替换结果。如果正则表达式有g标志,则会多次替换,直到全部替换完毕。replace方法会返回替换后的结果,但是对原字符串没有任何影响。<br><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> reg = <span class="regexp">/(\w+)\s(\w+)/</span>;</div><div class="line"><span class="keyword">var</span> str = <span class="string">'John Smith'</span>;</div><div class="line"><span class="keyword">var</span> newstr = str.replace(reg, <span class="string">'$2, $1'</span>); <span class="comment">//使用字符串参数替换</span></div><div class="line"><span class="built_in">console</span>.log(newstr); <span class="comment">// Smith, John</span></div><div class="line"></div><div class="line"><span class="comment">//下面写一个转换方法,用于将驼峰式命名转换成-连接</span></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">nameFormat</span>(<span class="params">oldName</span>) </span>{</div><div class="line"> <span class="keyword">return</span> oldName.replace(<span class="regexp">/[A-Z]/g</span>, <span class="function"><span class="keyword">function</span> (<span class="params">match</span>) </span>{</div><div class="line"> <span class="keyword">return</span> <span class="string">'-'</span> + match.toLowerCase();</div><div class="line"> }); </div><div class="line">}</div><div class="line"><span class="built_in">console</span>.log(nameFormat(<span class="string">'tooLongNameFor'</span>)); <span class="comment">//too-long-name-for</span></div></pre></td></tr></table></figure></p>
<p>字符串的 search 方法可以接收一个正则表达式对象作为参数,如果可以匹配,那么返回匹配的起始位置,否则返回-1。<br><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> str = <span class="string">'so wo know the number is 100, and total is 666.'</span>;</div><div class="line"><span class="keyword">var</span> reg = <span class="regexp">/(\w*)\s*is\s*(\d+)/</span>; </div><div class="line"><span class="built_in">console</span>.log(str.search(reg)); <span class="comment">//15</span></div></pre></td></tr></table></figure></p>
<p>字符串的 split 方法可以接收一个正则表达式对象作为参数,将字符串使用匹配的子串分隔。<br><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> str = <span class="string">'JavaScript,RegExp match,use'</span>;</div><div class="line"><span class="keyword">var</span> reg = <span class="regexp">/,|\s+|,/</span>; <span class="comment">//将使用英文逗号,中文逗号或者空格分隔的字符串分隔关键词</span></div><div class="line"><span class="built_in">console</span>.log(str.split(reg)); <span class="comment">//["JavaScript", "RegExp", "match", "use"]</span></div></pre></td></tr></table></figure></p>
<p>除了以上内容,还有 RegExp 这个类的一点知识点,每次执行依次正则表达式匹配,那么就会有一些信息被保存在 RegExp 类的静态属性上。RegExp 的 $1 到 $9 保存9个子表达式的匹配文本,lastMatch(简写 $&)是最后一个匹配的串,lastParen(简写 $+)是最后一个子表达式匹配的串,leftContext(简写 $`)是匹配串的左侧的所有文本,rightContext(简写 $’)是匹配串的右侧的所有文本,input 保存当前作用的字符串。</p>
<p>好了,JavaScript中的正则支持大概讲完了。</p>
]]></content>
<summary type="html">
<p>正则表达式是一种强大的工具,具体语法请看我的另一篇博客<a href="/2016/08/07/正则表达式入门/">正则表达式入门</a>,现在我们来看看正则表达式在JavaScript中的应用。<br>JavaScript对正则表达式的支持主要是由正则表达式类RegExp和字符串类String来提供的。</p>
<table>
<thead>
<tr>
<th>方法</th>
<th>所属类</th>
</tr>
</thead>
<tbody>
<tr>
<td>exec</td>
<td>RegExp</td>
</tr>
<tr>
<td>test</td>
<td>RegExp</td>
</tr>
<tr>
<td>match</td>
<td>String</td>
</tr>
<tr>
<td>replace</td>
<td>String</td>
</tr>
<tr>
<td>search</td>
<td>String</td>
</tr>
<tr>
<td>split</td>
<td>String</td>
</tr>
</tbody>
</table>
</summary>
<category term="正则表达式" scheme="http://lvu.me/categories/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/"/>
<category term="应用" scheme="http://lvu.me/categories/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/%E5%BA%94%E7%94%A8/"/>
<category term="javascript" scheme="http://lvu.me/tags/javascript/"/>
<category term="正则表达式" scheme="http://lvu.me/tags/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/"/>
</entry>
<entry>
<title>正则表达式入门</title>
<link href="http://lvu.me/2016/08/07/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%85%A5%E9%97%A8/"/>
<id>http://lvu.me/2016/08/07/正则表达式入门/</id>
<published>2016-08-07T05:24:59.000Z</published>
<updated>2016-08-07T10:48:52.000Z</updated>
<content type="html"><![CDATA[<p>正则表达式(regular expression,简称regex)是一种用来匹配和处理字符串的工具,它使用正则表达式语法创建,表现为字符串形式,由支持它的语言或者应用执行。我强烈推荐一本书《正则表达式必知必会》,内容浅显易懂。</p>
<p>下面是一些正则表达式的基础知识。</p>
<ol>
<li>.可以匹配任意字符,包括字母,数字,空白符,标点等</li>
<li>[和]定义一个字符组,匹配任何在该组中的字符(不含[和]),如[ab]匹配a和b,对于asc码连续的字符,可以使用-简写,如[a-z]匹配任何一个小写字母</li>
<li>[,]和^可以一起定义一个取非的字符组,如[^ab]匹配任何不是a,不是b的字符<a id="more"></a> </li>
<li>一些预定义的元字符,\n换行符,\r回车符,\t制表符(Tab键),\v垂直制表符,\f换页符,[\b]Backspace键</li>
<li>一些预定义的元字符组,\d任何一个数字字符(等价于[0-9]),\D任何一个非数字字符(等价于[^0-9]),\w任何一个字母数字字符或者下划线字符(等价于[0-9a-zA-Z_]),\W任何一个非字母数字或非下划线字符(等价于[^0-9a-zA-Z_]),\s任何一个空白符(等价于[\f\n\r\t\v]),\S任何一个非空白字符(等价于[^\f\n\r\t\v]),[\b]比较特殊,它在\S的覆盖范围里面</li>
<li>+匹配一个或多个,*匹配0个或多个,?匹配0个或1个</li>
<li>{n}匹配n个,{n,m}匹配最少n个,最多m个,{n, }匹配至少n个</li>
<li>常用的匹配元字符是贪婪型的,即它会尽可能多的匹配,比如字符串:abcdef,正则:.*,他会匹配整个字符串,而不是a或者别的。因此,我们可以使用它们的懒惰型版本,他会匹配尽可能少的字符。懒惰型版本是在贪婪型后面加一个?。*对应*?,+对应+?,{n, }对应{n, }?</li>
<li>\b匹配一个单词边界,即单词的开始或者单词的结束(单词指\w定义的字符或其组合),\B匹配非单词边界</li>
<li>^匹配一个字符串开头,$匹配一个字符串结尾,?m开启多行匹配(如果支持的话)</li>
<li>(和)定义一个子表达式,它将被视为一个独立的元素,(ab){3}匹配连续的3个ab,如 ababab</li>
<li>|字符是正则表达式里面的或字符,a|b将匹配a或者b</li>
<li>使用\1,\2等引用前面匹配的子表达式,这就是回溯匹配</li>
<li>(?=)正向前查找,(?!)负向前查找,(?<=)正向后查找,(?<!)负向后查找。此处的正指的匹配,负指的是不匹配,前指的是字符串中模式代表的部分右边,后指的是左边。此部分特性有的语言或者应用可能不支持不完整</li>
<li>回溯引用条件,使用形式:(?(backreference)true-regex|false-regex),其中backreference为回溯引用1,2等,不用\</li>
<li>前后查找条件,使用形式:(?(loookaround)true-regex|false-regex),其中loookaround为一个完整的前后查找表达式</li>
</ol>
<p>上面就是正则表达式的基本语法了,有些特性可能会有兼容性问题,使用时请查看具体语言的支持。<br>在具体使用正则表达式的时候,对于同一个问题,往往有多种解法,这是灵活性。不同的语言(如JavaScript,Java,PHP,Python,Perl,C#,C,C++等等),不同的应用(如grep,MySQL,Sublime等等)都支持正则表达式,当然他们的支持程度可能不一致,尤其是一些不常用的特性。<br>有一点需要牢记:把必须匹配的情况考虑周全并写出一个匹配结果符合预期的正则表达式很容易,但把不需要匹配的情况也考虑周全并确保它们都将被排除在匹配结果以外往往要困难得多。</p>
]]></content>
<summary type="html">
<p>正则表达式(regular expression,简称regex)是一种用来匹配和处理字符串的工具,它使用正则表达式语法创建,表现为字符串形式,由支持它的语言或者应用执行。我强烈推荐一本书《正则表达式必知必会》,内容浅显易懂。</p>
<p>下面是一些正则表达式的基础知识。</p>
<ol>
<li>.可以匹配任意字符,包括字母,数字,空白符,标点等</li>
<li>[和]定义一个字符组,匹配任何在该组中的字符(不含[和]),如[ab]匹配a和b,对于asc码连续的字符,可以使用-简写,如[a-z]匹配任何一个小写字母</li>
<li>[,]和^可以一起定义一个取非的字符组,如[^ab]匹配任何不是a,不是b的字符
</summary>
<category term="正则表达式" scheme="http://lvu.me/categories/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/"/>
<category term="入门" scheme="http://lvu.me/categories/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/%E5%85%A5%E9%97%A8/"/>
<category term="正则表达式" scheme="http://lvu.me/tags/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/"/>
</entry>
<entry>
<title>对linux文件权限的理解</title>
<link href="http://lvu.me/2016/08/03/%E5%AF%B9linux%E6%96%87%E4%BB%B6%E6%9D%83%E9%99%90%E7%9A%84%E7%90%86%E8%A7%A3/"/>
<id>http://lvu.me/2016/08/03/对linux文件权限的理解/</id>
<published>2016-08-03T00:06:02.000Z</published>
<updated>2016-08-06T03:04:16.000Z</updated>
<content type="html"><![CDATA[<p>*nix系统中,文件的各种权限比较重要,以下内容,是通过学习《鸟哥的linxu私房菜》之后总结的内容,方便自己理解和记忆。这篇文章最早发布于<a href="http://www.cnblogs.com/ilvu/p/4002992.html" target="_blank" rel="external">我的博客园</a>。</p>
<p>文件和目录都有权限:r、w 、x,并且对于 拥有者(属主),同组用户,其他用户 都有对应的权限限制。</p>
<ul>
<li>对于文件:r代表读,可读取文件的内容;w代表写,可修改文件的内容;x代表执行,可以执行文件</li>
<li>对于目录(记录文件清单):r代表可以列出其中文件的相关信息;w代表目录下文件和目录的删除、重命名、新建;x代表可以以该目录作为工作目录</li>
</ul>
<p>总结:</p>
<ul>
<li>文件的访问及使用限制由文件本身的权限决定,但是文件名称的修改、文件本身的删除是由文件所在目录的w权限决定的</li>
<li>文件的拥有着或者root可以修改文件或者目录的权限</li>
</ul>
<a id="more"></a>
<p>显然的,对于所有以文件的方式存在的命令,它们也有权限,所以,比如cd、ls等系统提供的命令也是有权限的,可以通过删除其x权限禁止用户使用该命令。<br>用户使用系统:即用户通过一个程序去操作文件或档案,要顺利进行这一动作,得满足两个条件:</p>
<ul>
<li>对该程序文件的执行权限,如对 cd 、ls 等的x权限</li>
<li>对要操作的目标文件的访问权限,如r,w</li>
</ul>
<p>举例:用户 dvid 进行操作:cat readme.md,首先 dvid 得具有 cat 程式的执行权限:x,其次 dvid 得具有 readme.md 的读权限:r。具体见下图<br><img title="linux文件权限演示" alt="linux文件权限演示" src="http://7xp584.com1.z0.glb.clouddn.com/static/images/2016-08-06-linux-authority.png"></p>
]]></content>
<summary type="html">
<p>*nix系统中,文件的各种权限比较重要,以下内容,是通过学习《鸟哥的linxu私房菜》之后总结的内容,方便自己理解和记忆。这篇文章最早发布于<a href="http://www.cnblogs.com/ilvu/p/4002992.html">我的博客园</a>。</p>
<p>文件和目录都有权限:r、w 、x,并且对于 拥有者(属主),同组用户,其他用户 都有对应的权限限制。</p>
<ul>
<li>对于文件:r代表读,可读取文件的内容;w代表写,可修改文件的内容;x代表执行,可以执行文件</li>
<li>对于目录(记录文件清单):r代表可以列出其中文件的相关信息;w代表目录下文件和目录的删除、重命名、新建;x代表可以以该目录作为工作目录</li>
</ul>
<p>总结:</p>
<ul>
<li>文件的访问及使用限制由文件本身的权限决定,但是文件名称的修改、文件本身的删除是由文件所在目录的w权限决定的</li>
<li>文件的拥有着或者root可以修改文件或者目录的权限</li>
</ul>
</summary>
<category term="linux" scheme="http://lvu.me/categories/linux/"/>
<category term="权限" scheme="http://lvu.me/categories/linux/%E6%9D%83%E9%99%90/"/>
<category term="权限" scheme="http://lvu.me/tags/%E6%9D%83%E9%99%90/"/>
<category term="命令" scheme="http://lvu.me/tags/%E5%91%BD%E4%BB%A4/"/>
</entry>
<entry>
<title>React Native环境搭建</title>
<link href="http://lvu.me/2016/07/14/React-Native%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/"/>
<id>http://lvu.me/2016/07/14/React-Native环境搭建/</id>
<published>2016-07-14T15:28:33.000Z</published>
<updated>2016-08-13T16:24:39.000Z</updated>
<content type="html"><![CDATA[<p>最近尝试了下React Native,<a href="https://facebook.github.io/react-native/docs/getting-started.html#content" target="_blank" rel="external">官网的安装教程</a>,已经写的非常详细了,但是我在环境配置的过程中,还是发现了一些大坑。</p>
<p><strong><em>重点是watchman的版本得是4.0以上!</em></strong></p>
<p>如果你按找官方的教程,搭建好了Android或者IOS的开发环境,安装了<a href="https://facebook.github.io/watchman" target="_blank" rel="external">watchman</a>,在使用react native跑示例程序的时候,报错,出现一些奇怪的报错,那么很大可能就是这个原因!尤其是mac,在可能已经安装了watchman的情况下,需要卸载老版本,重新安装最新的版本。</p>
<a id="more"></a>
<p>在mac上,可以使用Homebrew安装最新版watchman的命令是:<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">watchman -v <span class="comment">#查看watchman的版本</span></div><div class="line">brew uninstall watchman <span class="comment">#卸载</span></div><div class="line">brew unlink watchman </div><div class="line">brew install --HEAD watchman <span class="comment">#通过github直接安装最新版本的watchman</span></div></pre></td></tr></table></figure></p>
<p>如果是开发React Native的Android程序,那么需要先搭建Android开发环境,如果是开发IOS的程序,需要先搭建IOS的开发环境。<br>按照教程上的,如果是开发Android应用,那么需要配置Android开发环境,当然最方便的就是,直接下载Android官方开发工具<a href="https://developer.android.com/studio/install.html" target="_blank" rel="external">Android Studio</a>,如果不能翻墙上不去,就去这里找一找<a href="http://www.androiddevtools.cn/" target="_blank" rel="external">http://www.androiddevtools.cn/</a>。然后打开里面的Android SDK Manager下载相应的sdk、模拟器镜像等等,并将Android SDK的路径加入用户环境变量,用于在命令行被调用。注意MAC和windows平台上环境变量的设置。</p>
<p>对于Android方式,借助Android Studio可以方便地创建安卓模拟器、启动模拟器,然后,在其上跑React Native的应用。<br>对于IOS,好像只能是在mac上开发,有了xcode,安装ios模拟器之后,就和安卓的方式一样了。</p>
<p>下面列出一些Android开发常用的命令(来自android sdk,请确保android sdk路径已经被加入path环境变量),比如通过命令行创建模拟器或者启动模拟器,虚拟机即模拟器。<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">android list avd <span class="comment">#查看所有的虚拟机</span></div><div class="line">android create avd <span class="comment">#创建虚拟机</span></div><div class="line">emulator -avd avd-name <span class="comment">#启动虚拟机,avd-name 不要带后缀.avd</span></div><div class="line">adb devices <span class="comment">#查看已经启动的安卓设备(包括模拟器和通过usb连接的手机)</span></div></pre></td></tr></table></figure></p>
]]></content>
<summary type="html">
<p>最近尝试了下React Native,<a href="https://facebook.github.io/react-native/docs/getting-started.html#content">官网的安装教程</a>,已经写的非常详细了,但是我在环境配置的过程中,还是发现了一些大坑。</p>
<p><strong><em>重点是watchman的版本得是4.0以上!</em></strong></p>
<p>如果你按找官方的教程,搭建好了Android或者IOS的开发环境,安装了<a href="https://facebook.github.io/watchman">watchman</a>,在使用react native跑示例程序的时候,报错,出现一些奇怪的报错,那么很大可能就是这个原因!尤其是mac,在可能已经安装了watchman的情况下,需要卸载老版本,重新安装最新的版本。</p>
</summary>
<category term="JavaScript" scheme="http://lvu.me/categories/JavaScript/"/>
<category term="React" scheme="http://lvu.me/categories/JavaScript/React/"/>
<category term="javascript" scheme="http://lvu.me/tags/javascript/"/>
<category term="react" scheme="http://lvu.me/tags/react/"/>
<category term="react native" scheme="http://lvu.me/tags/react-native/"/>
</entry>
<entry>
<title>阳光正好</title>
<link href="http://lvu.me/2016/06/26/%E9%98%B3%E5%85%89%E6%AD%A3%E5%A5%BD/"/>
<id>http://lvu.me/2016/06/26/阳光正好/</id>
<published>2016-06-26T06:34:13.000Z</published>
<updated>2016-09-18T14:49:20.000Z</updated>
<content type="html"><![CDATA[<p>你所知道的一切,最终都会成为你的束缚。你的知识,决定了你会做出何种行为,当你的知识不够全面,不够客观,那么你容易做出自己觉得对的,但实际上不怎么正确的决定。<br>我们读书,或者旅行,或者和别人交流,或者反思,都可以让我们更好地认识世界,认识人生,认识自己,让自己具备全面的、客观的知识,从而做出正确的决定。<br>希望最后的我们,有信仰,有敬畏,有坚持,有原则,相信美好,选择善良,认真地生活。</p>
]]></content>
<summary type="html">
<p>你所知道的一切,最终都会成为你的束缚。你的知识,决定了你会做出何种行为,当你的知识不够全面,不够客观,那么你容易做出自己觉得对的,但实际上不怎么正确的决定。<br>我们读书,或者旅行,或者和别人交流,或者反思,都可以让我们更好地认识世界,认识人生,认识自己,让自己具备全面的
</summary>
<category term="随笔" scheme="http://lvu.me/categories/%E9%9A%8F%E7%AC%94/"/>
<category term="随笔" scheme="http://lvu.me/tags/%E9%9A%8F%E7%AC%94/"/>
</entry>
<entry>
<title>AnglarJS Tips(持续更新)</title>
<link href="http://lvu.me/2016/05/28/AnglarJS-Tips/"/>
<id>http://lvu.me/2016/05/28/AnglarJS-Tips/</id>
<published>2016-05-28T09:16:19.000Z</published>
<updated>2016-08-13T16:23:54.000Z</updated>
<content type="html"><![CDATA[<p>用AngularJS的人越来越多了,这里有一些重要的问题,可以作为对AngularJS的考察点。<br>以下内容,针对1.x版本。</p>
<p>1.AngularJS实现双向绑定的原理是什么?<br>2.$scope上$apply的作用是什么,什么时候需要你手动调用?<br>3.使用AngularJS的好处是什么?</p>
<p>以上问题,实际涉及到AngularJS的核心原理,能否清楚的回答,直接反映出你对AngularJS了解程度的深浅。</p>
<a id="more"></a>
<p>AngularJS作为一个MVC框架,一个很重要的功能就是数据绑定,即模型(model,具体体现为$scope对象)和视图(view,具体体现为指令模板)之间的数据同步,双向绑定呢,既有从模型到视图,也有视图到模型。我们使用ng-model这个指令来说明双向绑定的核心原理。<br>比如模板 <input ng-model=”model” />, 数据从视图到模型这个方向,ng-model指令通过在input这个元素上添加事件监听(change),当input的 值发生变化的时候,新值被写入$scope.model属性;对于数据从模型到视图这个方向,ng-model指令在$scope上进行了数据监听($watch),当监测到$scope.model被修改(比如ajax从后台获取数据),那么这个值就会被写入input的value。这就是双向绑定的整个过程。</p>
<p>经过上面的讨论,对于问题1,它的答案是:<strong><em>数据监听,视图到模型方向通过给模板中的DOM元素添加事件监听(典型的是change)完成,模型到视图方向通过给模型$scope添加属性监听($watch)实现,如此就可以实现数据在视图和模型之间的双向绑定了。</em></strong></p>
<p>上面说到,模型到视图是通过在$scope上添加属性监听($watch)实现的,那这里有个问题,这个事件监听是如何来实现监测对的呢,它是如何感知到$scope上属性的变化的呢,具体如何实现?视图到模型好说,最终可以通过DOM事件实现,那模型上呢?模型说到底就是一个JavaScript对象,它如何监测自己的变化?<br>在AngularJS的实现中,采用了一种称之为<strong><em>“脏数据检测”($digest,也有翻译“脏值检查”)</em></strong>的机制,即通过$scope的$watch方法,添加好多的检测表达式,以及变化时候的回调,然后在触发“脏数据检测”的时候,逐一执行这些检测表达式,比较这些表达式的值和上一次执行时候的值是否相同来确定$scope是否发生了变化,如果变化了,执行相应的回调方法,这样就能够对$scope的变化做出反应。那好,这里重点是它的实现方式,很显然,$scope还需要被触发去执行这个“脏数据检测”的过程,那么这个检测过程是什么时候被执行的呢?这就是AngularJS的核心原理了。<br>现在来说下“脏数据检测”的触发过程。“脏数据检测”是发生在每一个具体的$scope对象上的,对于某个$scope而言,进行“脏数据检测”实际上就是执行该$scope上的$digest方法。$scope上还有一个方法就是$apply,$apply是接受一个表达式,并在$scope上执行,最后会调用$digest,即触发“脏数据检测”。大多数时候,AngularJS会自行触发这个“脏数据检测”的过程,并不需要我们手动去调用$digest或者$apply,这也就是为什么我们在使用ng-model或者$http的时候,视图和模型已经自动关联的原因。<br>以下场景AngularJS会自动的调用$apply:</p>
<ul>
<li>angular启动的时候</li>
<li>angular事件绑定,如ng-click,ng-dblclick,ng-mousedown,ng-mouseup,ng-mouseover,ng-keydown等等</li>
<li>input,textarea, select等表单元素(实际上input,textarea,select是angular内部定义的指令,angluar中定义的指令可以有多种使用方式,这种就是“E”)</li>
<li>angular的部分内置服务,如 $http,$timeout等</li>
</ul>
<p>经过上面的讨论,我们来回答问题2。<strong><em>$apply是$scope上的一个方法,作用是在$scope上执行一个表达式,然后调用$digest,触发“脏数据检测”过程,实现模型和视图间的同步以及更新。除了上面所述的几种AngularJS会自动触发“脏数据检测”的场景,如果你在混用jQuery绑定DOM事件,调用外部的回调方法等等,这时候就需要手动调用$apply了。</em></strong></p>
<p>对于问题3,主要归纳下,就是:(1)AngularJS是一个MVC模式的框架,你可以分离控制逻辑、数据和渲染过程,各个部分职责明确,更加灵活;(2)AngularJS提供了指令这种强大的方式,让你可以扩展HTML,封装功能强大的独立组件;(3)AngularJS有模块的概念,可以将不同的部分放在不同的模块里面,结构清晰;(4)AngularJS提供了依赖注入的功能,让你可以方便地加载需要的服务或者模块等,并且这让测试变得很容易。</p>
<p>上述涉及到AngularJS核心的东西,大家可以查看源码进行对照(针对1.x版本)。这里附上一个stackoverflow上的链接:<a href="http://stackoverflow.com/questions/12463902/how-does-the-binding-and-digesting-work-in-angularjs" target="_blank" rel="external">how does the binding and digesting work in AngularJS?</a>,以示对照。</p>
]]></content>
<summary type="html">
<p>用AngularJS的人越来越多了,这里有一些重要的问题,可以作为对AngularJS的考察点。<br>以下内容,针对1.x版本。</p>
<p>1.AngularJS实现双向绑定的原理是什么?<br>2.$scope上$apply的作用是什么,什么时候需要你手动调用?<br>3.使用AngularJS的好处是什么?</p>
<p>以上问题,实际涉及到AngularJS的核心原理,能否清楚的回答,直接反映出你对AngularJS了解程度的深浅。</p>
</summary>
<category term="JavaScript" scheme="http://lvu.me/categories/JavaScript/"/>
<category term="AngularJS" scheme="http://lvu.me/categories/JavaScript/AngularJS/"/>
<category term="angularjs" scheme="http://lvu.me/tags/angularjs/"/>
<category term="javascript" scheme="http://lvu.me/tags/javascript/"/>
<category term="双向绑定" scheme="http://lvu.me/tags/%E5%8F%8C%E5%90%91%E7%BB%91%E5%AE%9A/"/>
<category term="脏数据检测" scheme="http://lvu.me/tags/%E8%84%8F%E6%95%B0%E6%8D%AE%E6%A3%80%E6%B5%8B/"/>
</entry>
<entry>
<title>随想</title>
<link href="http://lvu.me/2016/05/23/%E9%9A%8F%E6%83%B32016-05-23/"/>
<id>http://lvu.me/2016/05/23/随想2016-05-23/</id>
<published>2016-05-23T14:19:10.000Z</published>
<updated>2016-09-18T14:49:27.000Z</updated>
<content type="html"><![CDATA[<p>应该写一些东西了,总是会有几天,感悟颇多。</p>
<p>做事情应该面向结果,而不是面向过程。很多事情不是你做了就到此为止了,而是要看结果如何的。就比如一段代码,你觉得写完了ok了,但是你有没有在代码中留下一些坑呢,结果是否达到预期呢?这是对结果负责。更进一步,如果你做完之后,能够反思整个过程,是否哪里可以改进呢?这是对自己的提高。</p>
<p>反思是一种非常好的改进自我的方式,小到具体技巧的优化,大到整个人生思想水平的提高。这绝对可以让你的成长速度加倍,你可以用一年的时间收获他们两年的经验,你可以对同样的错误举一反三,绝不再犯。</p>
<p>思维方式真的能决定一个人的层次,然后决定你的生活。有些东西只要你意识到了,那么它就会对你的人生产生巨大的作用。</p>
]]></content>
<summary type="html">
<p>应该写一些东西了,总是会有几天,感悟颇多。</p>
<p>做事情应该面向结果,而不是面向过程。很多事情不是你做了就到此为止了,而是要看结果如何的。就比如一段代码,你觉得写完了ok了,但是你有没有在代码中留下一些坑呢,结果是否达到预期呢?这是对结果负责。更进一步,如果你做完之
</summary>
<category term="随笔" scheme="http://lvu.me/categories/%E9%9A%8F%E7%AC%94/"/>
<category term="随笔" scheme="http://lvu.me/tags/%E9%9A%8F%E7%AC%94/"/>
</entry>
<entry>
<title>JavaScript原型</title>
<link href="http://lvu.me/2015/12/15/JavaScript%E5%8E%9F%E5%9E%8B/"/>
<id>http://lvu.me/2015/12/15/JavaScript原型/</id>
<published>2015-12-15T14:39:17.000Z</published>
<updated>2016-07-31T04:48:35.000Z</updated>
<content type="html"><![CDATA[<p>JavaScript中对象的继承可以通过原型来实现,下面主要来说一下原型相关的问题。<br>以下是一些结论,详见文章内的验证:</p>
<ul>
<li>函数都有prototype属性,由函数构造的对象来继承。</li>
<li>普通对象都隐含一个其所继承的原型的属性__proto__,除了Object.prototype这个特殊对象等。</li>
<li>所有的函数都是Function类的实例。</li>
<li>所有的对象都是Object类的实例。</li>
<li>Function类是Object类的实例,Object函数也是Function类的实例。</li>
<li>所有的函数都是对象,所以函数既有prototype属性,也有__proto__属性。</li>
<li>原型链的最顶端是Object.prototype,该对象向上再没有原型了, Object.prototype.__proto__ === null。<br>由于Object.prototype这个对象比较特殊,它没有原型,会导致 Object.prototype instanceof Object 返回 false,这和instanceof的工作方式有关。</li>
</ul>
<a id="more"></a>
<p>我是很早就想对JS的原型链做一个总结,也推荐别人的一篇文章<a href="http://www.codeceo.com/article/javascript-prototype-learn.html" target="_blank" rel="external">JavaScript 原型概念深入理解</a>。</p>
<p>以下是验证图:<br><img title="属性在原型链中查找" alt="属性在原型链中查找" src="http://7xp584.com1.z0.glb.clouddn.com/static/images/2015-12-27-function-prototype.png"><br><img title="属性在原型链中查找" alt="属性在原型链中查找" src="http://7xp584.com1.z0.glb.clouddn.com/static/images/2015-12-27-function-prototype-2.png"><br><img title="函数都是Function类的实例" alt="函数都是Function类的实例" src="http://7xp584.com1.z0.glb.clouddn.com/static/images/function-instance.png"><br><img title="对象都是Object类的实例" alt="对象都是Object类的实例" src="http://7xp584.com1.z0.glb.clouddn.com/static/images/object-instance.png"><br><img title="Function和Object" alt="Function和Object" src="http://7xp584.com1.z0.glb.clouddn.com/static/images/2015-12-27-function-prototype-4.png"></p>
]]></content>
<summary type="html">
<p>JavaScript中对象的继承可以通过原型来实现,下面主要来说一下原型相关的问题。<br>以下是一些结论,详见文章内的验证:</p>
<ul>
<li>函数都有prototype属性,由函数构造的对象来继承。</li>
<li>普通对象都隐含一个其所继承的原型的属性__proto__,除了Object.prototype这个特殊对象等。</li>
<li>所有的函数都是Function类的实例。</li>
<li>所有的对象都是Object类的实例。</li>
<li>Function类是Object类的实例,Object函数也是Function类的实例。</li>
<li>所有的函数都是对象,所以函数既有prototype属性,也有__proto__属性。</li>
<li>原型链的最顶端是Object.prototype,该对象向上再没有原型了, Object.prototype.__proto__ === null。<br>由于Object.prototype这个对象比较特殊,它没有原型,会导致 Object.prototype instanceof Object 返回 false,这和instanceof的工作方式有关。</li>
</ul>
</summary>
<category term="JavaScript" scheme="http://lvu.me/categories/JavaScript/"/>
<category term="原型" scheme="http://lvu.me/categories/JavaScript/%E5%8E%9F%E5%9E%8B/"/>
<category term="javascript" scheme="http://lvu.me/tags/javascript/"/>
<category term="prototype" scheme="http://lvu.me/tags/prototype/"/>
<category term="原型" scheme="http://lvu.me/tags/%E5%8E%9F%E5%9E%8B/"/>
</entry>
<entry>
<title>angular的DOM编译过程</title>
<link href="http://lvu.me/2015/12/13/angular-compile/"/>
<id>http://lvu.me/2015/12/13/angular-compile/</id>
<published>2015-12-12T16:00:00.000Z</published>
<updated>2016-08-13T16:24:12.000Z</updated>
<content type="html"><![CDATA[<p>angular的DOM编译过程总的来说,是编译DOM,生成一个复合链接函数,然后传入scope作为参数,执行该链接函数,在scope和实际的DOM之间建立联系,编译过程结束。<br>下面主要来说一下编译DOM并生成链接函数的过程,以下分析基于<a href="https://github.com/Gpia/temp-data/blob/master/javascript/lib/angular-1.3.0.js" target="_blank" rel="external">angular-1.3.0源码</a>,由于代码很长,不在此贴出,可点击此链接查看,涉及到的内容主要从6094行开始。<br>编译DOM并生成链接函数的过程是由一个叫做compileNodes的内部方法完成的,该方法从一个指定的待编译节点列表开始编译,对于从document元素上启动的angular应用,那么待编译节点列表从一个只包含document元素(内部使用的是document的包装类型,即jqLite(document))的数组开始,形如 [jqLite(document)]。</p>
<a id="more"></a>
<p>一.具体来说compileNodes的过程:</p>
<p>1.对于待编译节点列表nodeList中的每一个节点node,收集它上面的指令(collectDirectives),然后对该节点node应用指令(applyDirectivesToNode),调用applyDirectivesToNode方法会返回一个当前node的链接函数nodeLinkFn;接着,如果有子节点,则重复步骤1,并传入子节点列表childNodes作为参数,生成childNodeLinkFn。<br>2.将nodeLinkFn和childLinkFn加入一个linkFns数组,保存(linkFns.push(i, nodeLinkFn, childLinkFn),i是node在nodeList中的索引)即linkFns中包含了待编译节点列表中每一个node的nodeLinkFn和childLinkFn。<br>3.返回一个复合链接函数compositeLinkFn。</p>
<p>通过以上3步compileNodes已经执行结束,此过程中DOM中指令的编译过程已经完成,即已经完成了指令的变换(applyDirectivesToNode方法),比如用指令的模板替换指令的占位元素。</p>
<p>还通过上述步骤,compileNodes返回的是一个复合链接函数compositeLinkFn,applyDirectivesToNode返回的是一个普通的链接函数nodeLinkFn,<br>复合链接函数用于执行当前节点node的nodeLinkFn和当前节点子节点的childLinkFn,其中由于childLinkFn是由compileNodes的递归调用返回的,所以它是一个复合链接函数,而当前节点的nodeLinkFn是由applyDirectivesToNode返回的,是一个普通的链接函数。即compositeLinkFn的执行到最后都是nodeLinkFn的执行。</p>
<p>实际上,上述步骤3返回的链接函数构成了一个闭包,它在执行时能够访问到上面的linkFns。</p>
<p>二.上面步骤3返回的的复合链接函数的执行过程(传入参数:scope,nodeList,rootElement。)</p>
<p>1.遍历linkFns,每一次遍历,都取出一个节点索引i,nodeLinkFn(普通链接函数)和childLinkFn(复合链接函数),通过nodeList[i]获取nodeLinkFn对应的节点node。<br>2.对于当前节点node,<br> 如果有nodeLinkFn,则首先根据nodeLinkFn包含的信息nodeLinkFn.scope生成恰当的子scope,如果有子scope,则childScope=scope.$new(),否则childScope=scope,然后执行nodeLinkFn,即nodeLinkFn(childLinkFn, childScope, node, $rootElement, childBoundTranscludeFn);<br> 如果没有nodeLinkFn,但有childLinkFn,则执行childLinkFn,即回到步骤1,继续执行子复合链接函数: childLinkFn(scope, node.childNodes, undefined, parentBoundTranscludeFn)。<br>3.执行结束。</p>
<p>重点说明:compileNodes方法处理的是模板DOM(对应compileNode),nodeLinkFn方法执行时是针对已经是编译后的DOM(对应linkNode),那么问题来了,linkFns数组中保存的node索引i,是在模板DOM中的顺序,而compositeLinkFn执行时却根据它从编译后的DOM中取node,对应不上?首先,对于有模板的指令,模板只能有一个根节点,即compileNode和linkNode是一一对应的,对于没有模板的指令,则compileNode===linkNode。再关键在于applyDirectivesToNode方法,该方法处理compileNode并最终返回了一个能够处理linkNode的nodeLinkFn,所以在nodeLinkFn在 最后执行的时候,既能够访问到compileNode(闭包),也能够访问到其该compileNode在变换之后对应的linkNode(参数),它在内部做了处理。</p>
<p>由上面我们知道,复合链接函数compileLinkFn的执行最后都是nodeLinkFn的执行,而nodeLinkFn是由applyDirectivesToNode方法返回的,顾名思义,它将指令应用到节点,完成了模板DOM到最终DOM的转换。</p>
<p>三.applyDirectivesToNode的执行过程(待完成)</p>
<p>四.nodeLinkFn的执行过程(待完成)</p>
]]></content>
<summary type="html">
<p>angular的DOM编译过程总的来说,是编译DOM,生成一个复合链接函数,然后传入scope作为参数,执行该链接函数,在scope和实际的DOM之间建立联系,编译过程结束。<br>下面主要来说一下编译DOM并生成链接函数的过程,以下分析基于<a href="https://github.com/Gpia/temp-data/blob/master/javascript/lib/angular-1.3.0.js">angular-1.3.0源码</a>,由于代码很长,不在此贴出,可点击此链接查看,涉及到的内容主要从6094行开始。<br>编译DOM并生成链接函数的过程是由一个叫做compileNodes的内部方法完成的,该方法从一个指定的待编译节点列表开始编译,对于从document元素上启动的angular应用,那么待编译节点列表从一个只包含document元素(内部使用的是document的包装类型,即jqLite(document))的数组开始,形如 [jqLite(document)]。</p>
</summary>
<category term="JavaScript" scheme="http://lvu.me/categories/JavaScript/"/>
<category term="AngularJS" scheme="http://lvu.me/categories/JavaScript/AngularJS/"/>
<category term="angularjs" scheme="http://lvu.me/tags/angularjs/"/>
<category term="javascript" scheme="http://lvu.me/tags/javascript/"/>
<category term="compile" scheme="http://lvu.me/tags/compile/"/>
<category term="编译" scheme="http://lvu.me/tags/%E7%BC%96%E8%AF%91/"/>
</entry>
</feed>