-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.xml
213 lines (102 loc) · 510 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>Session</title>
<link href="/2022/07/16/session/"/>
<url>/2022/07/16/session/</url>
<content type="html"><![CDATA[<p><span style="color:red">session默认有效期是30分钟</span></p><span id="more"></span><h2 id="设置session有效期"><a href="#设置session有效期" class="headerlink" title="设置session有效期"></a>设置session有效期</h2><p>***<span style="color:red">session默认有效期是30分钟</span>***,设置session的有效期有三种方法:</p><h3 id="1-在tomcat中的server-xml中定义:"><a href="#1-在tomcat中的server-xml中定义:" class="headerlink" title="1.在tomcat中的server.xml中定义:"></a>1.在tomcat中的server.xml中定义:</h3><p>在tomcat中的conf/server.xml文件可以修改服务器上的所有程序的默认有效期,设置单位为毫秒,定义代码如下:</p><pre class="language-xml" data-language="xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Context</span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/test<span class="token punctuation">"</span></span> <span class="token attr-name">docBase</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/test<span class="token punctuation">"</span></span> <span class="token attr-name">defaultSessionTimeOut</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>36000<span class="token punctuation">"</span></span> <span class="token attr-name">isWARExpanded</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span> <span class="token attr-name">isWARValidated</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span> <span class="token attr-name">isInvokerEnabled</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span> <span class="token attr-name">isWorkDirPersistent</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span></code></pre><h3 id="2-在工程的web-xml中定义:"><a href="#2-在工程的web-xml中定义:" class="headerlink" title="2.在工程的web.xml中定义:"></a>2.在工程的web.xml中定义:</h3><p>在工程web.xml中修改有效期,设置单位为分钟,定义代码如下:</p><pre class="language-xml" data-language="xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>session-config</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>session-timeout</span><span class="token punctuation">></span></span>60<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>session-timeout</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>session-config</span><span class="token punctuation">></span></span></code></pre><h3 id="3-通过Java代码设定:"><a href="#3-通过Java代码设定:" class="headerlink" title="3.通过Java代码设定:"></a>3.通过Java代码设定:</h3><p>设置单位为秒,设置为-1则表示永不过期</p><pre class="language-java" data-language="java"><code class="language-java">session<span class="token punctuation">.</span>setMaxInactiveInterval(<span class="token number">30</span><span class="token operator">*</span><span class="token number">60</span>)</code></pre><h2 id="session和cookie的区别"><a href="#session和cookie的区别" class="headerlink" title="session和cookie的区别"></a>session和cookie的区别</h2><h3 id="1-保存的位置不同"><a href="#1-保存的位置不同" class="headerlink" title="1.保存的位置不同"></a>1.保存的位置不同</h3><p>cookie保存在浏览器端,session保存在服务端。</p><h3 id="2-使用方式不同"><a href="#2-使用方式不同" class="headerlink" title="2.使用方式不同"></a>2.使用方式不同</h3><p>cookie如果在浏览器端对cookie进行设置对应的时间,则cookie保存在本地硬盘中,此时如果没有过期,则就可以使用,如果过期则就删除。如果没有对cookie设置时间,则默认关闭浏览器,则cookie就会删除。<br>session:我们在请求中,如果发送的请求中存在sessionId,则就会找到对应的session对象,如果不存在sessionId,则在服务器端就会创建一个session对象,并且将sessionId返回给浏览器,可以将其放到cookie中,进行传输,如果浏览器不支持cookie,则应该将其通过encodeURL(sessionID)进行调用,然后放到url中。</p><h3 id="3-存储内容不同"><a href="#3-存储内容不同" class="headerlink" title="3.存储内容不同"></a>3.存储内容不同</h3><p>cookie只能存储字符串,而session存储结构类似于hashtable的结构,可以存放任何类型。</p><h3 id="4-存储大小"><a href="#4-存储大小" class="headerlink" title="4.存储大小"></a>4.存储大小</h3><p>cookie最多可以存放4k大小的内容,session则没有限制。</p><h3 id="5-session的安全性要高于cooKie"><a href="#5-session的安全性要高于cooKie" class="headerlink" title="5.session的安全性要高于cooKie"></a>5.session的安全性要高于cooKie</h3><h3 id="6-cookie的session的应用场景"><a href="#6-cookie的session的应用场景" class="headerlink" title="6.cookie的session的应用场景"></a>6.cookie的session的应用场景</h3><p>cookie可以用来保存用户的登陆信息,如果删除cookie则下一次用户仍需要重新登录<br>session就类似于我们拿到钥匙去开锁,拿到的就是我们个人的信息,一般我们可以在session中存放个人的信息或者购物车的信息。</p><h3 id="7-session和cookie的弊端"><a href="#7-session和cookie的弊端" class="headerlink" title="7.session和cookie的弊端"></a>7.session和cookie的弊端</h3><p>cookie的大小受限制,cookie不安全,如果用户禁用cookie则无法使用cookie。如果过多的依赖session,当很多用户同时登陆的时候,此时服务器压力过大。sessionId存放在cookie中,此时如果对于一些浏览器不支持cookie,此时还需要改写代码,将sessionID放到url中,也是不安全。</p>]]></content>
<categories>
<category> 后端 </category>
</categories>
<tags>
<tag> Session </tag>
</tags>
</entry>
<entry>
<title>Oracle的一些语法</title>
<link href="/2022/01/22/Oracle/"/>
<url>/2022/01/22/Oracle/</url>
<content type="html"><![CDATA[<h2 id="merge-into语法"><a href="#merge-into语法" class="headerlink" title="merge into语法"></a>merge into语法</h2><blockquote><p> <strong>作用:判断B表和A表是否满足ON中条件,如果满足则用B表去更新A表,如果不满足,则将B表数据插入A表</strong></p></blockquote><pre class="language-sql" data-language="sql"><code class="language-sql"><span class="token keyword">MERGE</span> <span class="token keyword">INTO</span> <span class="token punctuation">[</span>target<span class="token operator">-</span><span class="token keyword">table</span><span class="token punctuation">]</span> A <span class="token keyword">USING</span> <span class="token punctuation">[</span>source<span class="token operator">-</span><span class="token keyword">table</span> <span class="token keyword">sql</span><span class="token punctuation">]</span> B <span class="token keyword">ON</span><span class="token punctuation">(</span><span class="token punctuation">[</span>conditional expression<span class="token punctuation">]</span> <span class="token operator">and</span> <span class="token punctuation">[</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token keyword">WHEN</span> <span class="token keyword">MATCHED</span> <span class="token keyword">THEN</span><span class="token punctuation">[</span><span class="token keyword">UPDATE</span> <span class="token keyword">sql</span><span class="token punctuation">]</span><span class="token keyword">WHEN</span> <span class="token operator">NOT</span> <span class="token keyword">MATCHED</span> <span class="token keyword">THEN</span><span class="token punctuation">[</span><span class="token keyword">INSERT</span> <span class="token keyword">sql</span><span class="token punctuation">]</span></code></pre><p>例:</p><pre class="language-sql" data-language="sql"><code class="language-sql"><span class="token keyword">merge</span> <span class="token keyword">into</span> TABLEA a <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token keyword">select</span> <span class="token string">'{0}'</span> <span class="token keyword">as</span> age<span class="token punctuation">,</span><span class="token string">'{1}'</span> <span class="token keyword">as</span> name<span class="token punctuation">,</span><span class="token string">'{2}'</span> <span class="token keyword">as</span> sex <span class="token keyword">from</span> dual<span class="token punctuation">)</span> b<span class="token keyword">on</span> <span class="token punctuation">(</span>a<span class="token punctuation">.</span>age<span class="token operator">=</span>b<span class="token punctuation">.</span>age<span class="token punctuation">)</span> <span class="token keyword">when</span> <span class="token keyword">matched</span> <span class="token keyword">then</span><span class="token keyword">update</span> <span class="token keyword">set</span> a<span class="token punctuation">.</span>name<span class="token operator">=</span>b<span class="token punctuation">.</span>name<span class="token punctuation">,</span>a<span class="token punctuation">.</span>sex<span class="token operator">=</span>b<span class="token punctuation">.</span>sex<span class="token keyword">when</span> <span class="token operator">not</span> <span class="token keyword">matched</span> <span class="token keyword">then</span><span class="token keyword">insert</span><span class="token punctuation">(</span>age<span class="token punctuation">,</span>name<span class="token punctuation">,</span>sex<span class="token punctuation">)</span> <span class="token keyword">values</span><span class="token punctuation">(</span>b<span class="token punctuation">.</span>age<span class="token punctuation">,</span>b<span class="token punctuation">.</span>name<span class="token punctuation">,</span>b<span class="token punctuation">.</span>sex<span class="token punctuation">)</span></code></pre><span id="more"></span><h3 id="虚拟表dual"><a href="#虚拟表dual" class="headerlink" title="虚拟表dual"></a>虚拟表dual</h3><p>此处b表dual为Oracle的虚拟表</p><blockquote><p><strong>dual 是一个实际存在的虚表,存在的目的不是为了保存数据,而是为了完善Oracle的查询语法规则</strong></p></blockquote><p>oracle保证dual里面永远只有一条记录</p><p><img src="https://img.wenhairu.com/images/2021/12/21/5UOzC.png" alt="image-dual" loading="lazy"></p><h2 id="获取GUID"><a href="#获取GUID" class="headerlink" title="获取GUID"></a>获取GUID</h2><blockquote><p>在.ashx文件中获取guid</p></blockquote><pre class="language-sql" data-language="sql"><code class="language-sql">var uid <span class="token operator">=</span> Guid<span class="token punctuation">.</span>NewGuid<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>ToString<span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre><blockquote><p>在.cs文件中获取guid</p></blockquote><pre class="language-sql" data-language="sql"><code class="language-sql">sys_guid<span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre><p>例:</p><pre class="language-sql" data-language="sql"><code class="language-sql"><span class="token keyword">select</span> sys_guid<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">from</span> dual</code></pre><h2 id="获取当前时间"><a href="#获取当前时间" class="headerlink" title="获取当前时间"></a>获取当前时间</h2><pre class="language-sql" data-language="sql"><code class="language-sql">sysdate</code></pre><h2 id="验证时间是否过期"><a href="#验证时间是否过期" class="headerlink" title="验证时间是否过期"></a>验证时间是否过期</h2><pre class="language-sql" data-language="sql"><code class="language-sql"><span class="token keyword">select</span> <span class="token operator">*</span> <span class="token keyword">from</span> <span class="token punctuation">(</span> <span class="token keyword">select</span> a<span class="token punctuation">.</span><span class="token operator">*</span><span class="token punctuation">,</span>ceil<span class="token punctuation">(</span><span class="token punctuation">(</span>sysdate <span class="token operator">-</span> ltime<span class="token punctuation">)</span><span class="token operator">*</span><span class="token number">24</span><span class="token operator">*</span><span class="token number">60</span><span class="token operator">*</span><span class="token number">60</span><span class="token punctuation">)</span>seconds <span class="token keyword">from</span> TABLEA a <span class="token punctuation">)</span> <span class="token keyword">where</span> seconds<span class="token operator"><</span><span class="token number">7000</span></code></pre><h2 id="查询表中总数据条数"><a href="#查询表中总数据条数" class="headerlink" title="查询表中总数据条数"></a>查询表中总数据条数</h2><pre class="language-sql" data-language="sql"><code class="language-sql"><span class="token keyword">select</span> <span class="token function">count</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">)</span> <span class="token keyword">from</span> <span class="token keyword">TABLE</span></code></pre><h2 id="多表查询-left-join"><a href="#多表查询-left-join" class="headerlink" title="多表查询 left join"></a>多表查询 left join</h2><blockquote><p><strong>left join 关键字从左表(table1)返回所有的行,即使右表(table2)中没有匹配。如果右表中没有匹配,则结果为 null</strong></p></blockquote><pre class="language-sql" data-language="sql"><code class="language-sql"><span class="token keyword">select</span> <span class="token operator">*</span> <span class="token keyword">from</span> table1 a<span class="token keyword">left</span> <span class="token keyword">join</span> table2 b <span class="token keyword">on</span> a<span class="token punctuation">.</span>name<span class="token operator">=</span>b<span class="token punctuation">.</span>name <span class="token operator">>></span><span class="token operator">></span>查找表table1和table2 </code></pre><h2 id="查询时格式化时间"><a href="#查询时格式化时间" class="headerlink" title="查询时格式化时间"></a>查询时格式化时间</h2><pre class="language-sql" data-language="sql"><code class="language-sql"><span class="token keyword">select</span> to_char<span class="token punctuation">(</span>t<span class="token punctuation">,</span><span class="token string">'yyyy-mm-dd hh24:mi:ss'</span><span class="token punctuation">)</span> time1 <span class="token keyword">from</span> table1</code></pre><h2 id="多值查询??where-in"><a href="#多值查询??where-in" class="headerlink" title="多值查询??where .. in ()"></a>多值查询??where .. in ()</h2><blockquote><p><strong>in 操作符允许在 WHERE 子句中规定多个值</strong></p></blockquote><pre class="language-sql" data-language="sql"><code class="language-sql"><span class="token keyword">select</span> <span class="token operator">*</span> <span class="token keyword">from</span> table1 <span class="token keyword">where</span> name <span class="token operator">in</span> <span class="token punctuation">(</span>name1<span class="token punctuation">,</span>name2<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span></code></pre><p>例:</p><pre class="language-sql" data-language="sql"><code class="language-sql"><span class="token keyword">select</span> <span class="token operator">*</span> <span class="token keyword">from</span> table1 <span class="token keyword">where</span> name <span class="token operator">in</span> <span class="token punctuation">(</span><span class="token keyword">select</span> name <span class="token keyword">from</span> table2<span class="token punctuation">)</span></code></pre><h2 id="模糊查询"><a href="#模糊查询" class="headerlink" title="模糊查询"></a>模糊查询</h2><pre class="language-sql" data-language="sql"><code class="language-sql"><span class="token keyword">select</span> <span class="token operator">*</span> <span class="token keyword">from</span> table1 <span class="token keyword">where</span> name <span class="token operator">like</span> <span class="token string">'%张%'</span> <span class="token operator">>></span><span class="token operator">></span>查询表table1中name字段包含张字的所有</code></pre><h2 id="存入图片"><a href="#存入图片" class="headerlink" title="存入图片"></a>存入图片</h2><pre class="language-sql" data-language="sql"><code class="language-sql"><span class="token keyword">public</span> <span class="token keyword">int</span> InsertImg<span class="token punctuation">(</span>string emp<span class="token punctuation">,</span> byte<span class="token punctuation">[</span><span class="token punctuation">]</span> signimg<span class="token punctuation">)</span>{ string <span class="token keyword">sql</span> <span class="token operator">=</span> string<span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span><span class="token variable">@"insert into table1(gid,emp,IMG,time1) values(sys_guid(),'{0}',:signimg,sysdate)"</span><span class="token punctuation">,</span>emp<span class="token punctuation">)</span><span class="token punctuation">;</span> OracleParameter<span class="token punctuation">[</span><span class="token punctuation">]</span> pms <span class="token operator">=</span> new OracleParameter<span class="token punctuation">[</span><span class="token punctuation">]</span> { new OracleParameter<span class="token punctuation">(</span><span class="token string">":signimg"</span><span class="token punctuation">,</span> OracleType<span class="token punctuation">.</span><span class="token keyword">Blob</span><span class="token punctuation">)</span>{<span class="token keyword">Value</span><span class="token operator">=</span>signimg} }<span class="token punctuation">;</span> <span class="token keyword">int</span> res <span class="token operator">=</span> ora<span class="token punctuation">.</span>ExecuteNonQuery<span class="token punctuation">(</span><span class="token keyword">sql</span><span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span><span class="token keyword">Text</span><span class="token punctuation">,</span> pms<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> res<span class="token punctuation">;</span>}</code></pre><h2 id="时间字段模糊查询"><a href="#时间字段模糊查询" class="headerlink" title="时间字段模糊查询"></a>时间字段模糊查询</h2><p>将Oracle中时间字段转化成字符串,然后进行字符串模糊查询</p><pre class="language-sql" data-language="sql"><code class="language-sql"><span class="token keyword">select</span> <span class="token operator">*</span> <span class="token keyword">from</span> <span class="token keyword">TABLE</span> <span class="token keyword">WHERE</span> to_char<span class="token punctuation">(</span>CREATE_TIME<span class="token punctuation">,</span><span class="token string">'yyyy-MM-dd'</span><span class="token punctuation">)</span> <span class="token operator">like</span> <span class="token string">'2019-09-12'</span></code></pre><h2 id="C-实现图片上传并保存相对路径"><a href="#C-实现图片上传并保存相对路径" class="headerlink" title="C#实现图片上传并保存相对路径"></a>C#实现图片上传并保存相对路径</h2><p><a href="https://q.cnblogs.com/q/87391/">C#实现图片上传并保存相对路径</a></p>]]></content>
<categories>
<category> Oracle </category>
</categories>
<tags>
<tag> SQL </tag>
<tag> 表查询 </tag>
</tags>
</entry>
<entry>
<title>平时遇到的一些方法</title>
<link href="/2022/01/22/something/"/>
<url>/2022/01/22/something/</url>
<content type="html"><![CDATA[<h2 id="radio设置属性checked属性不生效"><a href="#radio设置属性checked属性不生效" class="headerlink" title="radio设置属性checked属性不生效"></a>radio设置属性checked属性不生效</h2><blockquote><p>jq中使用attr()函数来设置选择框的checked属性有时会不起作用<span style="color:red;">(设置不生效)</span></p><pre class="language-js" data-language="js"><code class="language-js"><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">'#import'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">attr</span><span class="token punctuation">(</span><span class="token string">'checked'</span><span class="token punctuation">,</span><span class="token string">'checked'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>这时可以用prop()函数来设置就可以了<span style="color:#1BD66C">(正常设置成功)</span></p><pre class="language-js" data-language="js"><code class="language-js"><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">'#import'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">prop</span><span class="token punctuation">(</span><span class="token string">'checked'</span><span class="token punctuation">,</span><span class="token string">'checked'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></blockquote><h3 id="attr-和prop-的区别"><a href="#attr-和prop-的区别" class="headerlink" title="attr()和prop()的区别"></a>attr()和prop()的区别</h3><p>attr()方法主要是用来处理自定义的DOM属性;</p><p>prop()方法主要是用来处理本身就带有的固有属性</p><p>使用: <strong>具有true和false属性的属性,就使用prop(),比如checked selected disabled等,其他的使用attr()</strong></p><span id="more"></span><h2 id="mui获取单选、复选框的值"><a href="#mui获取单选、复选框的值" class="headerlink" title="mui获取单选、复选框的值"></a>mui获取单选、复选框的值</h2><blockquote><p>单选框获取值</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">getRadioRes</span><span class="token punctuation">(</span><span class="token parameter">className</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">var</span> rdsObj <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementsByClassName</span><span class="token punctuation">(</span>className<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> chackVal <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><span class="token keyword">for</span><span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> rdsObj<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">if</span> <span class="token punctuation">(</span>rdsObj<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>checked<span class="token punctuation">)</span> <span class="token punctuation">{</span>chackVal <span class="token operator">=</span> rdsObj<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>value<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token keyword">return</span> chackVal<span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><p>复选框获取值</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">getRadioRes</span><span class="token punctuation">(</span><span class="token parameter">className</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">var</span> rdsObj <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementsByClassName</span><span class="token punctuation">(</span>className<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/*获取值*/</span><span class="token keyword">var</span> checkVal <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> k <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> rdsObj<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">if</span> <span class="token punctuation">(</span>rdsObj<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>checked<span class="token punctuation">)</span> <span class="token punctuation">{</span>checkVal<span class="token punctuation">[</span>k<span class="token punctuation">]</span> <span class="token operator">=</span> rdsObj<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>value<span class="token punctuation">;</span>k<span class="token operator">++</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token keyword">return</span> checkVal<span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre></blockquote><h2 id="判断localStorage中指定属性是否存在"><a href="#判断localStorage中指定属性是否存在" class="headerlink" title="判断localStorage中指定属性是否存在"></a>判断localStorage中指定属性是否存在</h2><blockquote><p>1.</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">if</span> <span class="token punctuation">(</span>localStorage<span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span><span class="token string">"key"</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//自定义代码</span><span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">'key 存在'</span><span class="token punctuation">)</span><span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span><span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">'key 不存在'</span><span class="token punctuation">)</span><span class="token punctuation">}</span></code></pre><p>2.</p><pre class="language-js" data-language="js"><code class="language-js">localStorage<span class="token punctuation">.</span><span class="token function">hasOwnProperty</span><span class="token punctuation">(</span><span class="token string">'key'</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">'key 存在'</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">'key 不存在'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></blockquote><p><a href="https://www.cnblogs.com/LChenglong/p/7497368.html">localStorage的一些用法</a></p><h2 id="div禁用,不可点击"><a href="#div禁用,不可点击" class="headerlink" title="div禁用,不可点击"></a>div禁用,不可点击</h2><pre class="language-css" data-language="css"><code class="language-css"><span class="token selector">.notclick</span><span class="token punctuation">{</span><span class="token property">pointer-events</span><span class="token punctuation">:</span>none<span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><h2 id="特殊字符导致的json字符串转换json对象出问题的解决方法"><a href="#特殊字符导致的json字符串转换json对象出问题的解决方法" class="headerlink" title="特殊字符导致的json字符串转换json对象出问题的解决方法"></a>特殊字符导致的json字符串转换json对象出问题的解决方法</h2><pre class="language-js" data-language="js"><code class="language-js">att <span class="token operator">=</span> att<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">[\r\n]</span><span class="token regex-delimiter">/</span><span class="token regex-flags">g</span></span><span class="token punctuation">,</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h2 id="解决部分机型返回不刷新问题"><a href="#解决部分机型返回不刷新问题" class="headerlink" title="解决部分机型返回不刷新问题"></a>解决部分机型返回不刷新问题</h2><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">//解决部分机型返回不刷新问题</span>window<span class="token punctuation">.</span><span class="token function-variable function">onpageshow</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//event.persisted 是否从缓存中读取数据</span><span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>persisted<span class="token punctuation">)</span> <span class="token punctuation">{</span>window<span class="token punctuation">.</span>location<span class="token punctuation">.</span><span class="token function">reload</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre><h2 id="强制不换行"><a href="#强制不换行" class="headerlink" title="强制不换行"></a>强制不换行</h2><pre class="language-css" data-language="css"><code class="language-css"><span class="token property">white-space</span><span class="token punctuation">:</span>nowrap<span class="token punctuation">;</span></code></pre><h2 id="text-align-justify不生效的解决办法"><a href="#text-align-justify不生效的解决办法" class="headerlink" title="text-align: justify不生效的解决办法"></a>text-align: justify不生效的解决办法</h2><p>问题:text-align: justify样式在安卓可以正常两端对齐,iOS却不行</p><p>解决:</p><blockquote><p>添加text-align-last: justify;</p><pre class="language-css" data-language="css"><code class="language-css"><span class="token selector">.text</span> <span class="token punctuation">{</span> <span class="token property">text-align</span><span class="token punctuation">:</span> justify<span class="token punctuation">;</span> <span class="token property">text-align-last</span><span class="token punctuation">:</span> justify<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span>30px<span class="token punctuation">;</span><span class="token comment">/*注意这里要设置固定高度*/</span><span class="token punctuation">}</span></code></pre><p>然后添加伪元素::after,使文本不在最后一行</p><pre class="language-css" data-language="css"><code class="language-css"><span class="token selector">::after</span> <span class="token punctuation">{</span> <span class="token property">display</span><span class="token punctuation">:</span> inline-block<span class="token punctuation">;</span><span class="token comment">/*行内元素*/</span> <span class="token property">content</span><span class="token punctuation">:</span> <span class="token string">''</span><span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span><span class="token comment">/*可以挤掉文字,保证不跟文字在同一行*/</span> <span class="token property">height</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">visibility</span><span class="token punctuation">:</span> hidden<span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre></blockquote><h2 id="JS正则表达式只允许数字,分号和连字符"><a href="#JS正则表达式只允许数字,分号和连字符" class="headerlink" title="JS正则表达式只允许数字,分号和连字符"></a>JS正则表达式只允许数字,分号和连字符</h2><pre class="language-js" data-language="js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^\d+((;\d+)*|-\d+)?$</span><span class="token regex-delimiter">/</span></span></code></pre><p><code>(;\d+)*</code>将检查分隔多个号码“;”</p><p><code>-\d+</code>将检查范围</p><h2 id="jq获取多个相同name名的input框的value值"><a href="#jq获取多个相同name名的input框的value值" class="headerlink" title="jq获取多个相同name名的input框的value值"></a>jq获取多个相同name名的input框的value值</h2><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"input[name='question']"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">each</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>arr<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token function">$</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">val</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h2 id="获取ID含有特殊字符的DOM元素"><a href="#获取ID含有特殊字符的DOM元素" class="headerlink" title="获取ID含有特殊字符的DOM元素"></a>获取ID含有特殊字符的DOM元素</h2><blockquote><p>原生js</p><pre class="language-js" data-language="js"><code class="language-js">document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span>rowId<span class="token punctuation">)</span></code></pre><p>jq:使用属性选择器</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">// 将所有的id值用双引号包起来,即可进行识别</span><span class="token comment">// 请注意双引号添加的位置,只在id上进行包裹</span><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">'[id="'</span> <span class="token operator">+</span> rowId <span class="token operator">+</span> <span class="token string">'"]'</span><span class="token punctuation">)</span></code></pre></blockquote><h2 id="获取指定时间的时间戳"><a href="#获取指定时间的时间戳" class="headerlink" title="获取指定时间的时间戳"></a>获取指定时间的时间戳</h2><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">getTargetTime</span><span class="token punctuation">(</span><span class="token parameter">t</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>t<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span></code></pre><h2 id="时间戳转换为日期"><a href="#时间戳转换为日期" class="headerlink" title="时间戳转换为日期"></a>时间戳转换为日期</h2><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">add0</span><span class="token punctuation">(</span><span class="token parameter">m</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">return</span> m <span class="token operator"><</span> <span class="token number">10</span> <span class="token operator">?</span> <span class="token string">'0'</span> <span class="token operator">+</span> m <span class="token operator">:</span> m<span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">format</span><span class="token punctuation">(</span><span class="token parameter">shijianchuo</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//shijianchuo是整数,否则要parseInt转换</span><span class="token keyword">var</span> time <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>shijianchuo<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> y <span class="token operator">=</span> time<span class="token punctuation">.</span><span class="token function">getFullYear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> m <span class="token operator">=</span> time<span class="token punctuation">.</span><span class="token function">getMonth</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">var</span> d <span class="token operator">=</span> time<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> h <span class="token operator">=</span> time<span class="token punctuation">.</span><span class="token function">getHours</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> mm <span class="token operator">=</span> time<span class="token punctuation">.</span><span class="token function">getMinutes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> s <span class="token operator">=</span> time<span class="token punctuation">.</span><span class="token function">getSeconds</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> y <span class="token operator">+</span> <span class="token string">'-'</span> <span class="token operator">+</span> <span class="token function">add0</span><span class="token punctuation">(</span>m<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">'-'</span> <span class="token operator">+</span> <span class="token function">add0</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">' '</span> <span class="token operator">+</span> <span class="token function">add0</span><span class="token punctuation">(</span>h<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">':'</span> <span class="token operator">+</span> <span class="token function">add0</span><span class="token punctuation">(</span>mm<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">':'</span> <span class="token operator">+</span> <span class="token function">add0</span><span class="token punctuation">(</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><h2 id="js金额转大写"><a href="#js金额转大写" class="headerlink" title="js金额转大写"></a>js金额转大写</h2><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">intToChinese</span><span class="token punctuation">(</span><span class="token parameter">money</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//汉字的数字</span> <span class="token keyword">var</span> cnNums <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token string">'零'</span><span class="token punctuation">,</span> <span class="token string">'壹'</span><span class="token punctuation">,</span> <span class="token string">'贰'</span><span class="token punctuation">,</span> <span class="token string">'叁'</span><span class="token punctuation">,</span> <span class="token string">'肆'</span><span class="token punctuation">,</span> <span class="token string">'伍'</span><span class="token punctuation">,</span> <span class="token string">'陆'</span><span class="token punctuation">,</span> <span class="token string">'柒'</span><span class="token punctuation">,</span> <span class="token string">'捌'</span><span class="token punctuation">,</span> <span class="token string">'玖'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//基本单位</span> <span class="token keyword">var</span> cnIntRadice <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token string">''</span><span class="token punctuation">,</span> <span class="token string">'拾'</span><span class="token punctuation">,</span> <span class="token string">'佰'</span><span class="token punctuation">,</span> <span class="token string">'仟'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//对应整数部分扩展单位</span> <span class="token keyword">var</span> cnIntUnits <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token string">''</span><span class="token punctuation">,</span> <span class="token string">'万'</span><span class="token punctuation">,</span> <span class="token string">'亿'</span><span class="token punctuation">,</span> <span class="token string">'兆'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//对应小数部分单位</span> <span class="token keyword">var</span> cnDecUnits <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token string">'角'</span><span class="token punctuation">,</span> <span class="token string">'分'</span><span class="token punctuation">,</span> <span class="token string">'毫'</span><span class="token punctuation">,</span> <span class="token string">'厘'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//整数金额时后面跟的字符</span> <span class="token keyword">var</span> cnInteger <span class="token operator">=</span> <span class="token string">'整'</span><span class="token punctuation">;</span> <span class="token comment">//整型完以后的单位</span> <span class="token keyword">var</span> cnIntLast <span class="token operator">=</span> <span class="token string">'元'</span><span class="token punctuation">;</span> <span class="token comment">//最大处理的数字</span> <span class="token keyword">var</span> maxNum <span class="token operator">=</span> <span class="token number">999999999999999.9999</span><span class="token punctuation">;</span> <span class="token comment">//金额整数部分</span> <span class="token keyword">var</span> integerNum<span class="token punctuation">;</span> <span class="token comment">//金额小数部分</span> <span class="token keyword">var</span> decimalNum<span class="token punctuation">;</span> <span class="token comment">//输出的中文金额字符串</span> <span class="token keyword">var</span> chineseStr <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">;</span> <span class="token comment">//分离金额后用的数组,预定义</span> <span class="token keyword">var</span> parts<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>money <span class="token operator">===</span> <span class="token string">''</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//不能用==</span> <span class="token keyword">return</span> <span class="token string">''</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> money <span class="token operator">=</span> <span class="token function">parseFloat</span><span class="token punctuation">(</span>money<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>money <span class="token operator">>=</span> maxNum<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//超出最大处理数字</span> <span class="token keyword">return</span> <span class="token string">''</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>money <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> chineseStr <span class="token operator">=</span> cnNums<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">+</span> cnIntLast <span class="token operator">+</span> cnInteger<span class="token punctuation">;</span> <span class="token keyword">return</span> chineseStr<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">//转换为字符串</span> money <span class="token operator">=</span> money<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>money<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token string">'.'</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> integerNum <span class="token operator">=</span> money<span class="token punctuation">;</span> decimalNum <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> parts <span class="token operator">=</span> money<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">'.'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> integerNum <span class="token operator">=</span> parts<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span> decimalNum <span class="token operator">=</span> parts<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">//获取整型部分转换</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">parseInt</span><span class="token punctuation">(</span>integerNum<span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> zeroCount <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">var</span> IntLen <span class="token operator">=</span> integerNum<span class="token punctuation">.</span>length<span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> IntLen<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> n <span class="token operator">=</span> integerNum<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span>i<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> p <span class="token operator">=</span> IntLen <span class="token operator">-</span> i <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">var</span> q <span class="token operator">=</span> p <span class="token operator">/</span> <span class="token number">4</span><span class="token punctuation">;</span> <span class="token keyword">var</span> m <span class="token operator">=</span> p <span class="token operator">%</span> <span class="token number">4</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">==</span> <span class="token string">'0'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> zeroCount<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>zeroCount <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> chineseStr <span class="token operator">+=</span> cnNums<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">//归零</span> zeroCount <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> chineseStr <span class="token operator">+=</span> cnNums<span class="token punctuation">[</span><span class="token function">parseInt</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token operator">+</span> cnIntRadice<span class="token punctuation">[</span>m<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>m <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">&&</span> zeroCount <span class="token operator"><</span> <span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> chineseStr <span class="token operator">+=</span> cnIntUnits<span class="token punctuation">[</span>q<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> chineseStr <span class="token operator">+=</span> cnIntLast<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">//小数部分</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>decimalNum <span class="token operator">!=</span> <span class="token string">''</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> decLen <span class="token operator">=</span> decimalNum<span class="token punctuation">.</span>length<span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> decLen<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> n <span class="token operator">=</span> decimalNum<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span>i<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">!=</span> <span class="token string">'0'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> chineseStr <span class="token operator">+=</span> cnNums<span class="token punctuation">[</span><span class="token function">Number</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token operator">+</span> cnDecUnits<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>chineseStr <span class="token operator">==</span> <span class="token string">''</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> chineseStr <span class="token operator">+=</span> cnNums<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">+</span> cnIntLast <span class="token operator">+</span> cnInteger<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>decimalNum <span class="token operator">==</span> <span class="token string">''</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> chineseStr <span class="token operator">+=</span> cnInteger<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> chineseStr<span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><h2 id="数组对象相关"><a href="#数组对象相关" class="headerlink" title="数组对象相关"></a>数组对象相关</h2><p>有一个数组对象前来参加</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">{</span><span class="token string">"id"</span><span class="token operator">:</span> <span class="token string">"1"</span><span class="token punctuation">,</span><span class="token string">"name"</span><span class="token operator">:</span> <span class="token string">"小黑"</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token string">"id"</span><span class="token operator">:</span> <span class="token string">"2"</span><span class="token punctuation">,</span><span class="token string">"name"</span><span class="token operator">:</span> <span class="token string">"小白"</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token string">"id"</span><span class="token operator">:</span> <span class="token string">"3"</span><span class="token punctuation">,</span><span class="token string">"name"</span><span class="token operator">:</span> <span class="token string">"小灰"</span><span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre><h3 id="判断数组对象中是否包含某个值"><a href="#判断数组对象中是否包含某个值" class="headerlink" title="判断数组对象中是否包含某个值"></a>判断数组对象中是否包含某个值</h3><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">/** * 判断数组对象中是否有某个值 * array 要查询的数组 * attr 要查询的字段 * val 要查询的字段值 */</span><span class="token keyword">function</span> <span class="token function">findElem</span><span class="token punctuation">(</span><span class="token parameter">array<span class="token punctuation">,</span> attr<span class="token punctuation">,</span> val</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> array<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">if</span> <span class="token punctuation">(</span>array<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span>attr<span class="token punctuation">]</span> <span class="token operator">==</span> val<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">return</span> i<span class="token punctuation">;</span> <span class="token comment">//返回当前索引值</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">findElem</span><span class="token punctuation">(</span>arr<span class="token punctuation">,</span> <span class="token string">'name'</span><span class="token punctuation">,</span> <span class="token string">'小白'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment">//为-1表示不存在,否则返回查询到的第一个下标</span></code></pre><h3 id="返回包含指定值的对象"><a href="#返回包含指定值的对象" class="headerlink" title="返回包含指定值的对象"></a>返回包含指定值的对象</h3><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">//返回包含指定值的对象</span><span class="token keyword">var</span> status <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//返回arr中包含id=2的对象</span><span class="token keyword">return</span> obj<span class="token punctuation">.</span>id <span class="token operator">==</span> <span class="token number">2</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h3 id="根据数组对象属性删除里面的对象"><a href="#根据数组对象属性删除里面的对象" class="headerlink" title="根据数组对象属性删除里面的对象"></a>根据数组对象属性删除里面的对象</h3><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">/* * 根据数组对象属性删除对应项 * @param {Array} arr - 数组对象 * @param {String} attr - 属性 * @param {} value - 属性值 * @return void */</span> <span class="token function">removeByValue</span><span class="token punctuation">(</span><span class="token parameter">arr<span class="token punctuation">,</span> attr<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> index<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token keyword">in</span> arr<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span>attr<span class="token punctuation">]</span><span class="token operator">==</span>value<span class="token punctuation">)</span><span class="token punctuation">{</span> index<span class="token operator">=</span>i<span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> arr<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span>index<span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">// 移除id=2的项</span><span class="token function">removeByValue</span><span class="token punctuation">(</span>arr<span class="token punctuation">,</span> <span class="token string">'id'</span><span class="token punctuation">,</span> <span class="token string">'2'</span><span class="token punctuation">)</span></code></pre><h3 id="根据数组对象某一属性值排序"><a href="#根据数组对象某一属性值排序" class="headerlink" title="根据数组对象某一属性值排序"></a>根据数组对象某一属性值排序</h3><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">compare</span><span class="token punctuation">(</span><span class="token parameter">property</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">return</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span>b</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">var</span> value1 <span class="token operator">=</span> a<span class="token punctuation">[</span>property<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">var</span> value2 <span class="token operator">=</span> b<span class="token punctuation">[</span>property<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">return</span> value1<span class="token operator">-</span>value2<span class="token punctuation">;</span> <span class="token comment">//正序 [value2-value1为逆序]</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token keyword">var</span> result <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token function">compare</span><span class="token punctuation">(</span><span class="token string">'id'</span><span class="token punctuation">)</span><span class="token punctuation">)</span></code></pre><h3 id="数组对象去重"><a href="#数组对象去重" class="headerlink" title="数组对象去重"></a>数组对象去重</h3><blockquote><p>方法1:利用对象访问属性的方法,判断对象中是否存在key</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> result <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span> i<span class="token operator"><</span>arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span>obj<span class="token punctuation">[</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">{</span> result<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> obj<span class="token punctuation">[</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre><p>方法2:利用reduce方法遍历数组,reduce第一个参数是遍历需要执行的函数,第二个参数是item的初始值</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>arr <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">item<span class="token punctuation">,</span> next</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>obj<span class="token punctuation">[</span>next<span class="token punctuation">.</span>key<span class="token punctuation">]</span> <span class="token operator">?</span> <span class="token string">''</span> <span class="token operator">:</span> obj<span class="token punctuation">[</span>next<span class="token punctuation">.</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token operator">&&</span> item<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>next<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> item<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></blockquote><h2 id="删除数组中的指定值"><a href="#删除数组中的指定值" class="headerlink" title="删除数组中的指定值"></a>删除数组中的指定值</h2><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"123"</span><span class="token punctuation">,</span> <span class="token string">"456"</span><span class="token punctuation">,</span> <span class="token string">"789"</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">function</span> <span class="token function">removeByValue</span><span class="token punctuation">(</span><span class="token parameter">arr<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> index<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token keyword">in</span> arr<span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">if</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">==</span>value<span class="token punctuation">)</span><span class="token punctuation">{</span> index<span class="token operator">=</span>i<span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span><span class="token punctuation">}</span> <span class="token punctuation">}</span> arr<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span>index<span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">removeByValue</span><span class="token punctuation">(</span>arr<span class="token punctuation">,</span> <span class="token string">'123'</span><span class="token punctuation">)</span></code></pre><h2 id="图片转base64"><a href="#图片转base64" class="headerlink" title="图片转base64"></a>图片转base64</h2><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">getBase64Image</span><span class="token punctuation">(</span><span class="token parameter">img</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> canvas <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"canvas"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> canvas<span class="token punctuation">.</span>width <span class="token operator">=</span> img<span class="token punctuation">.</span>width<span class="token punctuation">;</span> canvas<span class="token punctuation">.</span>height <span class="token operator">=</span> img<span class="token punctuation">.</span>height<span class="token punctuation">;</span> <span class="token keyword">var</span> ctx <span class="token operator">=</span> canvas<span class="token punctuation">.</span><span class="token function">getContext</span><span class="token punctuation">(</span><span class="token string">"2d"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> ctx<span class="token punctuation">.</span><span class="token function">drawImage</span><span class="token punctuation">(</span>img<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> img<span class="token punctuation">.</span>width<span class="token punctuation">,</span> img<span class="token punctuation">.</span>height<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> ext <span class="token operator">=</span> img<span class="token punctuation">.</span>src<span class="token punctuation">.</span><span class="token function">substring</span><span class="token punctuation">(</span>img<span class="token punctuation">.</span>src<span class="token punctuation">.</span><span class="token function">lastIndexOf</span><span class="token punctuation">(</span><span class="token string">"."</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> dataURL <span class="token operator">=</span> canvas<span class="token punctuation">.</span><span class="token function">toDataURL</span><span class="token punctuation">(</span><span class="token string">"image/"</span><span class="token operator">+</span>ext<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> dataURL<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> image <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Image</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> image<span class="token punctuation">.</span>src <span class="token operator">=</span> <span class="token string">"../img.png"</span><span class="token punctuation">;</span> image<span class="token punctuation">.</span><span class="token function-variable function">onload</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">var</span> base64 <span class="token operator">=</span> <span class="token function">getBase64Image</span><span class="token punctuation">(</span>image<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>base64<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre><h2 id="JS对象与字符串相互转换"><a href="#JS对象与字符串相互转换" class="headerlink" title="JS对象与字符串相互转换"></a>JS对象与字符串相互转换</h2><blockquote><p>对象转字符串</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span></code></pre><p>json字符串转json对象</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span></code></pre></blockquote>]]></content>
<categories>
<category> JS </category>
</categories>
<tags>
<tag> js </tag>
<tag> 小结 </tag>
</tags>
</entry>
<entry>
<title>node.js&MongoDB</title>
<link href="/2021/12/16/node/"/>
<url>/2021/12/16/node/</url>
<content type="html"><![CDATA[<h2 id="NodeJS介绍和安装"><a href="#NodeJS介绍和安装" class="headerlink" title="NodeJS介绍和安装"></a>NodeJS介绍和安装</h2><h3 id="什么是Node-js"><a href="#什么是Node-js" class="headerlink" title="什么是Node.js"></a>什么是Node.js</h3><ul><li>Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境(采用Google开发的V8引擎运行js代码)</li><li>Node.js 使用了事件驱动、非阻塞式 I/O 的模型,使其轻量又高效</li><li><img src="https://img.wenhairu.com/images/2021/12/16/5Whiu.png" alt="image-20201208211110291" loading="lazy"></li></ul><h3 id="Node-js使用场景"><a href="#Node-js使用场景" class="headerlink" title="Node.js使用场景"></a>Node.js使用场景</h3><ul><li>高并发</li><li>即时通讯</li><li>推送消息</li></ul><h3 id="Node-js的特性"><a href="#Node-js的特性" class="headerlink" title="Node.js的特性"></a>Node.js的特性</h3><ul><li>它是一个JavaScript运行环境</li><li>依赖于Chrome V8引擎</li><li>轻量,适于实时数据交互应用</li><li>单线程</li><li>非阻塞I/O</li><li>事件驱动</li></ul><span id="more"></span><h4 id="单线程"><a href="#单线程" class="headerlink" title="单线程"></a>单线程</h4><p>像java、python这个可以具有多线程的语言。多线程同步模式是这样的,将cpu分成几个线程,每个线程同步运行。Node.js不会为每个客户连接创建一个新的线程,而仅使用一个线程。也就是说每一个计算独占cpu,遇到I/O请求不阻塞后面的计算,当I/O完成后,以事件的方式通知,继续执行计算2。</p><p><img src="https://img.wenhairu.com/images/2021/12/16/5WvFh.png" alt="image-20201208212945303" loading="lazy"></p><h4 id="非阻塞I-O"><a href="#非阻塞I-O" class="headerlink" title="非阻塞I/O"></a>非阻塞I/O</h4><pre class="language-none"><code class="language-none">I/O(英语:Input/Output),即输入/输出,通常指数据在内部存储器和外部存储器或其他周边设备之间的输入和输出。而在程序执行的过程中会有很多的I/O操作,如读写文件,请求响应,数据库的读写等等</code></pre><p>非阻塞I/O也就是指程序在执行的过程中,I/O操作不会阻塞程序的执行,也就是在执行I/o操作时,程序的的执行不受影响,继续执行其他的代码(这主要得益于node的事件循环机制),很显然这种非阻塞I/O大大提高了程序的性能。</p><p>nodejs 会保证主线程不会被阻塞,如果遇到正在执行的IO操作。nodejs 会把io操作放到其他地方去执行。(通过事件驱动来执行)。系统会把这个操作挪动事件队列里面执行。执行结束的任务会以回调函数的形式,返回给线程。然后继续处理接下来的任务。</p><h4 id="事件驱动"><a href="#事件驱动" class="headerlink" title="事件驱动"></a>事件驱动</h4><p><img src="https://img.wenhairu.com/images/2021/12/16/5WLoI.png" alt="事件驱动的模型" loading="lazy"></p><p>Nodejs 会把所有请求和异步操作都放到一个事件队列中,用户的每一个请求就是一个事件。主线程先把普通(同步任务)代码执行完毕,然后会循环事件队列里的函数,如果遇到有IO的操作,nodejs会去线程池里拿出一个线程去执行IO的操作,执行完毕后再把拿到数据的回调函数,放到事件队列的尾部,继续事件循环,当主线程再次循环到该事件时,就直接处理并返回给上层调用。 这个过程就叫 <strong>事件循环</strong> (Event Loop)</p><p><img src="https://img.wenhairu.com/images/2021/12/16/5Wtzp.png" alt="img" loading="lazy"></p><pre class="language-none"><code class="language-none">应用层: 即 JavaScript 交互层,常见的就是 Node.js 的模块,比如 http,fsV8引擎层: 即利用 V8 引擎来解析JavaScript 语法,进而和下层 API 交互NodeAPI层: 为上层模块提供系统调用,一般是由 C 语言来实现,和操作系统进行交互 。LIBUV层: 是跨平台的底层封装,实现了 事件循环、文件操作等,是 Node.js 实现异步的核心 </code></pre><h3 id="Node-js安装"><a href="#Node-js安装" class="headerlink" title="Node.js安装"></a>Node.js安装</h3><p>Node.js官网: <a href="https://nodejs.org/en/">https://nodejs.org/en/</a><br>Node.js中文网: <a href="http://nodejs.cn/">http://nodejs.cn/</a> </p><p> 下载安装【傻瓜式下一步】 Current是当前最新版本 LTS是长期支持版本<br> 查看Node.js版本: 终端 中输入 node -v </p><h4 id="终端"><a href="#终端" class="headerlink" title="终端"></a>终端</h4><p>通常将命令行程序称为终端 </p><p>打开方式:</p><pre class="language-none"><code class="language-none">1.win+r 运行窗口 cmd2.在文件夹url地址栏中输入 cmd 回车3.在文件夹中,按shift+右键,找powershell4.vscode 在集成终端中打开</code></pre><p>可以在终端中通过”命令”去执行一些操作<br>可以用命令打开电脑中某个文件、创建某个文件夹、查看电脑的IP等等 </p><pre class="language-none"><code class="language-none">dir 查看文件目录cd 文件名 进入下一级cd ../ 向上一级cls 清屏操作新建文件夹:mkdir+文件夹名字,mkdir与文件名之间一定要有空格rmdir 文件夹名字 删除文件夹table键:补全命令“ifconfig”:查看IP地址tree:以树状形状显示目录结构。盘符:进入某个磁盘 d:</code></pre><h4 id="运行文件"><a href="#运行文件" class="headerlink" title="运行文件"></a>运行文件</h4><pre class="language-none"><code class="language-none">终端中输入 node 文件名</code></pre><h3 id="Node-js模块"><a href="#Node-js模块" class="headerlink" title="Node.js模块"></a>Node.js模块</h3><ul><li>在Node.js中,以模块为单位去划分功能</li><li>Node.js中也提供了完整的模块加载机制</li><li>一个js文件就是一个模块,多个模块可以相互引用,多个模块作为整体也可看作是一个广义上的模块</li><li>node应用由模块组成,采用的commonjs模块规范。每一个文件就是一个模块,拥有自己独立的作用域,变量,以及方法等,对其他的模块都不可见。CommonJS规范规定,每个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。require方法用于加载模块。</li><li>可以有多个exports,引入只有一个require</li><li>也可以用来向外暴露一个类</li></ul><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">//代码</span><span class="token comment">//first.js</span><span class="token keyword">function</span> <span class="token function">say</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>msg<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// say();</span><span class="token comment">// console.log(module);</span>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> say<span class="token punctuation">;</span><span class="token comment">//second.js</span><span class="token keyword">let</span> fir <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./first.js'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>fir<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">fir</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h4 id="模块的优点"><a href="#模块的优点" class="headerlink" title="模块的优点"></a>模块的优点</h4><p>减少重复代码,提高代码利用率<br>以功能划分,便于模块管理<br>方便使用第三方模块</p><h2 id="搭建后台"><a href="#搭建后台" class="headerlink" title="搭建后台"></a>搭建后台</h2><h3 id="http模块"><a href="#http模块" class="headerlink" title="http模块"></a>http模块</h3><ul><li>借助http模块,通过几行代码能实现一个迷你web server</li><li>http模块是Node.js重要的核心模块</li><li><img src="https://img.wenhairu.com/images/2021/12/16/5WxnP.png" alt="image-20201209213129530" loading="lazy"></li></ul><p>http.Server 类:用来搭建一个服务,帮助接受请求,发送响应<br>http.ServerResponse 类:响应请求,设置响应的内容等</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">//引入http包</span><span class="token keyword">let</span> http <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'http'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//http.createServer 返回http.Server实例</span><span class="token keyword">let</span> serve <span class="token operator">=</span> http<span class="token punctuation">.</span><span class="token function">createServer</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span>res</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">// res:response 服务器的响应</span> <span class="token comment">// req:request 接受的前端的请求</span> <span class="token comment">// 设置响应头内容</span> res<span class="token punctuation">.</span><span class="token function">writeHead</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span><span class="token punctuation">{</span> <span class="token string">'content-type'</span><span class="token operator">:</span><span class="token string">'text/html;charset=utf-8'</span><span class="token punctuation">,</span> <span class="token string">'Access-Control-Allow-Origin'</span><span class="token operator">:</span><span class="token string">'*'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//res.write(); //write() 会发送一块响应主体</span> res<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//res.end(data,callback);</span> <span class="token comment">//此方法向服务器发出信号,表明已发送所有响应头和主体,该服务器应该视为此消息已完成,响应结束。 必须在每个响应上调用此 response.end() 方法。</span> <span class="token comment">//如果指定了 data,则相当于调用 response.write(data) 之后再调用 response.end(callback)。</span> <span class="token comment">//如果指定了 callback,则当响应流完成时将调用它</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//serve.listen(端口号,主机名,callback)启动 HTTP 服务器用于监听连接;</span></code></pre><p><a href="http://nodejs.cn/api/http.html">官方API文档</a></p><h3 id="url模块"><a href="#url模块" class="headerlink" title="url模块"></a>url模块</h3><h4 id="url模块作用"><a href="#url模块作用" class="headerlink" title="url模块作用"></a>url模块作用</h4><ul><li><p>对请求的URL进行处理和解析</p></li><li><p>也可以对URL进行格式化的操作</p></li><li><p> 使用方法如下:</p></li></ul> <pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">const</span> url <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'url'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>URL 字符串是结构化的字符串,包含多个含义不同的组成部分。 解析字符串后返回的 URL 对象,每个属性对应字符串的各个组成部分。</p><p><img src="https://img.wenhairu.com/images/2021/12/16/5D6VD.png" alt="image-20201209231714518" loading="lazy"></p><h4 id="url模块常用API"><a href="#url模块常用API" class="headerlink" title="url模块常用API"></a>url模块常用API</h4><p>url.parse():将一个url字符串解析并且返回一个url对象<br>url.format():对一个url对象进行格式化操作,返回一个url字符串<br>url.resolve():返回一个”from/to”的字符串,相当于对路径进行拼接</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> http <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'http'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> url <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'url'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token string">'李逵'</span><span class="token punctuation">,</span>age<span class="token operator">:</span><span class="token number">18</span><span class="token punctuation">,</span>job<span class="token operator">:</span><span class="token string">'杀老虎'</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token string">'高俅'</span><span class="token punctuation">,</span>age<span class="token operator">:</span><span class="token number">38</span><span class="token punctuation">,</span>job<span class="token operator">:</span><span class="token string">'踢球'</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token string">'高俅'</span><span class="token punctuation">,</span>age<span class="token operator">:</span><span class="token number">38</span><span class="token punctuation">,</span>job<span class="token operator">:</span><span class="token string">'宦官'</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token string">'宋江'</span><span class="token punctuation">,</span>age<span class="token operator">:</span><span class="token number">28</span><span class="token punctuation">,</span>job<span class="token operator">:</span><span class="token string">'梁山扛把子'</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token string">'西门庆'</span><span class="token punctuation">,</span>age<span class="token operator">:</span><span class="token number">25</span><span class="token punctuation">,</span>job<span class="token operator">:</span><span class="token string">'不干好事'</span><span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">;</span>http<span class="token punctuation">.</span><span class="token function">createServer</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span>res</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span>req<span class="token punctuation">.</span>url <span class="token operator">===</span> <span class="token string">'/favicon.ico'</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">;</span> res<span class="token punctuation">.</span><span class="token function">writeHead</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token string">'Content-type'</span><span class="token operator">:</span> <span class="token string">'text/plain;charset=utf-8'</span><span class="token punctuation">,</span> <span class="token string">'Access-Control-Allow-Origin'</span><span class="token operator">:</span> <span class="token string">'*'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// let url_obj = url.parse(req.url); </span> <span class="token comment">// let names = url_obj.query.split('=')[1]</span> <span class="token comment">// console.log(url_obj, names, decodeURI(names));</span> <span class="token keyword">let</span> url_obj <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>req<span class="token punctuation">.</span>url<span class="token punctuation">,</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token string">'name'</span> <span class="token keyword">in</span> url_obj<span class="token punctuation">.</span>query<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">let</span> result <span class="token operator">=</span> person<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{</span> <span class="token keyword">return</span> item<span class="token punctuation">.</span>name<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>url_obj<span class="token punctuation">.</span>query<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> res<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">//WHATWG url</span> <span class="token comment">// let url_ = new URL(req.url,'http:127.0.0.1:2020');</span> <span class="token comment">// console.log(url_.searchParams.get('name'));</span> res<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">listen</span><span class="token punctuation">(</span><span class="token number">2020</span><span class="token punctuation">,</span><span class="token string">'127.0.0.1'</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'running.......'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><pre class="language-JS" data-language="JS"><code class="language-JS">// format() 格式化一个url let url_str = url.format({ protocol:'http', hostname:'www.qianduan0371.com', port:12345, pathname:'/index/demo', query:{ name:"lisi", age:12 }, hash:'format_demo' }); res.write(url_str);//resolve let url1 = url.resolve('/one/two/three', 'four'); // '/one/two/four' let url2 = url.resolve('http://example.com/', '/one'); // 'http://example.com/one' let url3 = url.resolve('http://example.com/one', '/two'); // 'http://example.com/two' console.log(url1,url2,url3);</code></pre><h3 id="什么是nodejs路由"><a href="#什么是nodejs路由" class="headerlink" title="什么是nodejs路由"></a>什么是nodejs路由</h3><p>通过请求的URL路径和其他需要的 GET 及 POST 参数来区分不同的请求,随后路由需要根据这些数据来执行相应的代码(路由就可以通过这些URL路径和参数准确找到对应功能代码上)。因此,我们需要查看 HTTP 请求,从中提取出请求的 URL 以及 GET/POST 参数</p><pre class="language-none"><code class="language-none">//例如http://127.0.0.1:2020/login 登录http://127.0.0.1:2020/register 注册</code></pre><pre class="language-js" data-language="js"><code class="language-js">案例功能:<span class="token comment">//例如</span>http<span class="token operator">:</span><span class="token operator">/</span><span class="token operator">/</span><span class="token number">127.0</span><span class="token number">.0</span><span class="token number">.1</span><span class="token operator">:</span><span class="token number">2020</span><span class="token operator">/</span>add 添加http<span class="token operator">:</span><span class="token operator">/</span><span class="token operator">/</span><span class="token number">127.0</span><span class="token number">.0</span><span class="token number">.1</span><span class="token operator">:</span><span class="token number">2020</span><span class="token operator">/</span>search 查询添加用户信息(用户名、年龄) 查询用户(用户名)接口地址:http<span class="token operator">:</span><span class="token operator">/</span><span class="token operator">/</span><span class="token number">127.0</span><span class="token number">.0</span><span class="token number">.1</span><span class="token operator">:</span><span class="token number">2020</span><span class="token operator">/</span><span class="token function">add</span><span class="token punctuation">(</span>search<span class="token punctuation">)</span>请求方式:<span class="token keyword">get</span>参数:用户名:name 年龄:age</code></pre><h2 id="前后端交互"><a href="#前后端交互" class="headerlink" title="前后端交互"></a>前后端交互</h2><h3 id="fs模块"><a href="#fs模块" class="headerlink" title="fs模块"></a>fs模块</h3><p>在Node.js中,对文件和文件夹进行操作,比如读取,创建等,用来管理文件的系统的模块<br>也可以在响应过程中读取指定的文件内容,比如html文件或者jpg文件等,并且把这些作为响应内容</p><h3 id="fs常用API"><a href="#fs常用API" class="headerlink" title="fs常用API"></a>fs常用API</h3><p>fs.readFile():用来读取文件内容的函数<br>fs.readdir():读取一个文件夹的内容<br>fs.writeFile():文件写入内容<br>fs.mkdir():创建文件夹<br>fs.stat():检测文件状态</p><p>案例:</p><h3 id="静态资源管理"><a href="#静态资源管理" class="headerlink" title="静态资源管理"></a>静态资源管理</h3><p>问题:启动服务,在浏览器里无法直接查看图片,CSS等静态资源<br>解决方案:通过fs模块解决静态文件加载的问题</p><p>案例:</p><h3 id="Get请求"><a href="#Get请求" class="headerlink" title="Get请求"></a>Get请求</h3><p>參考nodejs路由功能</p><h2 id="第三方模块"><a href="#第三方模块" class="headerlink" title="第三方模块"></a>第三方模块</h2><h3 id="npm安装和使用"><a href="#npm安装和使用" class="headerlink" title="npm安装和使用"></a><a href="https://www.npmjs.cn/">npm安装和使用</a></h3><h3 id="npm-是什么?"><a href="#npm-是什么?" class="headerlink" title="npm 是什么?"></a>npm 是什么?</h3><p>npm是随同Node.js一起安装的包管理工具<br>通过npm可以共享使用各式JS开源库,对JS开源库的版本可以直接快速的管理,使用这些基于模块开发方式让团队更好的协作开发 npm 为你和你的团队打开了连接整个 JavaScript 天才世界的一扇大门。它是世界上最大的软件注册表,每星期大约有 30 亿次的下载量,包含超过 600000 个 <em>包(package)</em> (即,代码模块)</p><h3 id="更新-npm"><a href="#更新-npm" class="headerlink" title="更新 npm"></a>更新 npm</h3><p>安装node.js时,将自动安装npm。但是,npm的更新频率比Node.js的更新频率高,因此请确保您具有最新版本。</p><p>获取当前版本,请运行<code>npm -v</code>。</p><p>更新到最新版本,请运行:</p><p><code>npm install npm@latest -g</code></p><pre class="language-none"><code class="language-none">安装模块npm install <package name> 本地安装npm install -g <package name> 全局安装</code></pre><pre class="language-none"><code class="language-none">npm list: 查看安装信息</code></pre><pre class="language-none"><code class="language-none">npm uninstall <package name>:卸载本地包npm update <package name>:更新本地包npm uninstall -g <package name>:卸载全局包npm update -g <package name>:更新全局包</code></pre><pre class="language-none"><code class="language-none">cnpm的安装和使用由于npm的服务器在国外(即在“墙”外),国(墙)内开发者做项目的时候,很多“包”的下载速度极慢,在这种环境下阿里巴巴为了众多开发者的便捷便挺身而出推出了淘宝镜像(即cnpm),它把npm官方的“包”全部搬到国内,供广大开发者使用。cnpm的官方介绍是:cnpm是一个完整 npmjs.org 镜像,你可以用此代替官方版本(只读),同步频率目前为 10分钟 一次以保证尽量与官方服务同步。安装指令:npm install cnpm -g --registry=https://registry.npm.taobao.org</code></pre><p><img src="https://img.wenhairu.com/images/2021/12/16/5Df7N.jpg" alt="img" loading="lazy"></p><h3 id="安装练习:"><a href="#安装练习:" class="headerlink" title="安装练习:"></a>安装练习:</h3><p><a href="https://underscorejs.net/">underscore.js</a></p><h2 id="package-json文件详解"><a href="#package-json文件详解" class="headerlink" title="package.json文件详解"></a>package.json文件详解</h2><p>作用:定义了在这个项目中,需要的各种模块,以及项目的配置信息<br>比如名称,版本等内容,通过npm install指令,就可以通过这个文件的内容,自动下载对应模块,配置项目所需的开发环境</p><p>管理本地安装的npm软件包的最佳方法是创建一个 <code>package.json</code>文件。</p><p>一个<code>package.json</code>文件:</p><ul><li>列出您的项目所依赖的软件包。</li><li>允许您使用<a href="https://www.npmjs.cn/getting-started/using-a-package.json/docs.npmjs.com/getting-started/semantic-versioning">语义版本控制规则</a>指定项目可以使用的软件包的<a href="https://www.npmjs.cn/getting-started/using-a-package.json/docs.npmjs.com/getting-started/semantic-versioning">版本</a>。</li><li>使您的构建具有可复制性,因此<em>更</em>易于与其他开发人员共享。</li></ul><h3 id="创建package-json文件"><a href="#创建package-json文件" class="headerlink" title="创建package.json文件"></a>创建package.json文件</h3><pre class="language-none"><code class="language-none">//方法1npm init//方法2npm init -y(--yes)</code></pre><h3 id="package文件重要属性"><a href="#package文件重要属性" class="headerlink" title="package文件重要属性"></a>package文件重要属性</h3><ul><li>name:项目名或者包名</li><li>version:版本号</li><li>description:描述</li><li>author:作者</li><li>scripts:运行脚本命令的npm命令行缩写</li><li>dependencies:项目运行所依赖的模块,一般用于生产环境(您的应用程序在生产中需要这些软件包)</li><li>devDependencies:项目开发所需要的模块,一般用于开发环境(这些软件包仅在开发和测试时需要)</li></ul><h3 id="在-save和-save-dev安装标志"><a href="#在-save和-save-dev安装标志" class="headerlink" title="在--save和--save-dev安装标志"></a>在<code>--save</code>和<code>--save-dev</code>安装标志</h3><p>向您的依赖项中添加依赖项的更简单(更棒)方法<code>package.json</code>是从命令行执行此操作,<code>npm install</code>并使用<code>--save</code>或 标记该命令<code>--save-dev</code>,具体取决于您希望如何使用该依赖项。</p><p>要将条目添加到您<code>package.json</code>的中<code>dependencies</code>:</p><pre class="language-none"><code class="language-none">npm install <package_name> --save</code></pre><p>要将条目添加到您<code>package.json</code>的中<code>devDependencies</code>:</p><pre class="language-none"><code class="language-none">npm install <package_name> --save-dev</code></pre><p>指定版本:比如1.8.3<br>波浪号<del>+指定版本:比如</del>1.8.3,不低于1.8.3,安装不会改变大版本和次版本<br>插入号^+指定版本:比如^1.8.3,安装不改变大版本<br>latest:安装最新版本</p><h3 id="package和npm配合使用"><a href="#package和npm配合使用" class="headerlink" title="package和npm配合使用"></a>package和npm配合使用</h3><p>把已经配置好的package文件,通过npm进行自动安装(npm install ),完成开发环境的搭建</p><p>package-lock.json 是在 <code>npm install</code>时候生成一份文件,用来记录当前状态下实际安装的各个npm package的具体来源和版本号。npm最新的版本就开始提供自动生成package-lock.json功能,为的是让开发者知道只要你保存了源文件,到一个新的机器上、或者新的下载源,只要按照这个package-lock.json所标示的具体版本下载依赖库包,就能确保所有库包与你上次安装的完全一样。</p><h3 id="post请求"><a href="#post请求" class="headerlink" title="post请求"></a>post请求</h3><ul><li><p>form表单POST请求</p></li><li><p>Ajax POST请求</p></li></ul><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">const</span> http <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'http'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">const</span> querystring <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'querystring'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>http<span class="token punctuation">.</span><span class="token function">createServer</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span>res</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span>req<span class="token punctuation">.</span>url <span class="token operator">===</span> <span class="token string">'/favicon.ico'</span><span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token comment">// console.log(req);</span> <span class="token keyword">if</span><span class="token punctuation">(</span>req<span class="token punctuation">.</span>method<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token string">'POST'</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">// 接收post 提交上来的数据</span> <span class="token comment">// 数据接收 分段接收。</span> <span class="token comment">// 会触发俩个事件</span> <span class="token keyword">var</span> alldata <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">;</span> req<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'data'</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">v</span><span class="token punctuation">)</span><span class="token punctuation">{</span> alldata<span class="token operator">+=</span>v<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> req<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'end'</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> alldata <span class="token operator">=</span> querystring<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>alldata<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>alldata<span class="token punctuation">)</span><span class="token punctuation">;</span> res<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>alldata<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">listen</span><span class="token punctuation">(</span><span class="token number">12345</span><span class="token punctuation">,</span><span class="token string">'127.0.0.1'</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'running......'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span></code></pre><p> 文件上传 </p><p> 借助 formidable 第三方模块处理接收文件</p><h2 id="Express框架"><a href="#Express框架" class="headerlink" title="Express框架"></a>Express框架</h2><p><a href="https://www.expressjs.com.cn/">Express框架</a></p><p>基于 <a href="https://nodejs.org/en/">Node.js</a> 平台,快速、开放、极简的 Web 开发框架。</p><h3 id="安装…"><a href="#安装…" class="headerlink" title="安装…"></a>安装…</h3><h3 id="路由…"><a href="#路由…" class="headerlink" title="路由…"></a>路由…</h3><h3 id="静态文件…"><a href="#静态文件…" class="headerlink" title="静态文件…"></a>静态文件…</h3><h3 id="Express生成器…"><a href="#Express生成器…" class="headerlink" title="Express生成器…"></a>Express生成器…</h3><h2 id="MongoDB"><a href="#MongoDB" class="headerlink" title="MongoDB"></a>MongoDB</h2><h3 id="什么是MongoDB"><a href="#什么是MongoDB" class="headerlink" title="什么是MongoDB ?"></a>什么是MongoDB ?</h3><p>MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。</p><p>在高负载的情况下,添加更多的节点,可以保证服务器性能。</p><p>MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。</p><p>MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。</p><p><img src="https://img.wenhairu.com/images/2021/12/16/5DYKR.png" alt="image-20201216232842393" loading="lazy"></p><h3 id="MongoDB-下载"><a href="#MongoDB-下载" class="headerlink" title="MongoDB 下载"></a>MongoDB 下载</h3><p>你可以在mongodb官网下载该安装包,地址为:<a href="https://www.mongodb.com/download-center#community%E3%80%82">https://www.mongodb.com/download-center#community。</a></p><h3 id="Windows-平台安装-MongoDB"><a href="#Windows-平台安装-MongoDB" class="headerlink" title="Windows 平台安装 MongoDB"></a><a href="https://www.runoob.com/mongodb/mongodb-window-install.html"><strong>Windows 平台安装</strong> <strong>MongoDB</strong></a></h3><ul><li>完整安装</li><li>自定义安装</li></ul><h3 id="链接MongoDB"><a href="#链接MongoDB" class="headerlink" title="链接MongoDB"></a>链接MongoDB</h3><ul><li>完整安装<ul><li>默认安装c盘,找到MongoDB/Server/bin/ 运行mongo.exe,出现一下界面,链接成功</li><li><img src="https://img.wenhairu.com/images/2021/12/16/5DmuS.png" alt="image-20201217060244089" loading="lazy"></li></ul></li></ul><h3 id="MongoDB-概念解析"><a href="#MongoDB-概念解析" class="headerlink" title="MongoDB 概念解析"></a>MongoDB 概念解析</h3><p>在mongodb中基本的概念是文档、集合、数据库。</p><table><thead><tr><th><em><strong>*SQL术语/概念*</strong></em></th><th><em><strong>*MongoDB术语/概念*</strong></em></th><th><em><strong>*解释/说明*</strong></em></th></tr></thead><tbody><tr><td>database</td><td>database</td><td>数据库</td></tr><tr><td>table</td><td>collection</td><td>数据库表/集合</td></tr><tr><td>row</td><td>document</td><td>数据记录行/文档</td></tr><tr><td>column</td><td>field</td><td>数据字段/域</td></tr><tr><td>index</td><td>index</td><td>索引</td></tr><tr><td>table joins</td><td></td><td>表连接,MongoDB不支持</td></tr><tr><td>primary key</td><td>primary key</td><td>主键,MongoDB自动将_id字段设置为主键</td></tr></tbody></table><p>通过下图实例,我们也可以更直观的了解Mongo中的一些概念:</p><p><img src="https://img.wenhairu.com/images/2021/12/16/5DqZC.jpg" alt="img" loading="lazy"> </p><h3 id="数据库"><a href="#数据库" class="headerlink" title="数据库"></a>数据库</h3><p>一个mongodb中可以建立多个数据库。</p><p>MongoDB的默认数据库为”db”,该数据库存储在data目录中。</p><p>MongoDB的单个实例可以容纳多个独立的数据库,每一个都有自己的集合和权限,不同的数据库也放置在不同的文件中。</p><p><em><strong>*“show dbs”*</strong></em> 命令可以显示所有数据库的列表。</p><p>执行 <em><strong>*“db”*</strong></em> 命令可以显示当前数据库对象或集合。</p><p>运行”use”命令,可以连接到一个指定的数据库。</p><h3 id="文档"><a href="#文档" class="headerlink" title="文档"></a>文档</h3><p>文档是一组键值(key-value)对(即BSON)。****MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型****,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点。</p><p>下表列出了 RDBMS 与 MongoDB 对应的术语:</p><table><thead><tr><th><em><strong>*RDBMS*</strong></em></th><th><em><strong>*MongoDB*</strong></em></th></tr></thead><tbody><tr><td>数据库</td><td>数据库</td></tr><tr><td>表格</td><td>集合</td></tr><tr><td>行</td><td>文档</td></tr><tr><td>列</td><td>字段</td></tr><tr><td>表联合</td><td>嵌入文档</td></tr><tr><td>主键</td><td>主键 (MongoDB 提供了 key 为 _id )</td></tr><tr><td><em><strong>*数据库服务和客户端*</strong></em></td><td></td></tr><tr><td>Mysqld/Oracle</td><td>mongod</td></tr><tr><td>mysql/sqlplus</td><td>mongo</td></tr></tbody></table><h3 id="集合"><a href="#集合" class="headerlink" title="集合"></a>集合</h3><p>集合就是 MongoDB 文档组,类似于 RDBMS (关系数据库管理系统:Relational Database Management System)中的表格。</p><p>集合存在于数据库中,集合没有固定的结构,这意味着你在对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性。</p><h3 id="MongoDB-数据类型"><a href="#MongoDB-数据类型" class="headerlink" title="MongoDB 数据类型"></a>MongoDB 数据类型</h3><p>下表为MongoDB中常用的几种数据类型。</p><table><thead><tr><th><em><strong>*数据类型*</strong></em></th><th><em><strong>*描述*</strong></em></th></tr></thead><tbody><tr><td>String</td><td>字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。</td></tr><tr><td>Integer</td><td>整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。</td></tr><tr><td>Boolean</td><td>布尔值。用于存储布尔值(真/假)。</td></tr><tr><td>Double</td><td>双精度浮点值。用于存储浮点值。</td></tr><tr><td>Min/Max keys</td><td>将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。</td></tr><tr><td>Array</td><td>用于将数组或列表或多个值存储为一个键。</td></tr><tr><td>Timestamp</td><td>时间戳。记录文档修改或添加的具体时间。</td></tr><tr><td>Object</td><td>用于内嵌文档。</td></tr><tr><td>Null</td><td>用于创建空值。</td></tr><tr><td>Symbol</td><td>符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。</td></tr><tr><td>Date</td><td>日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。</td></tr><tr><td>Object ID</td><td>对象 ID。用于创建文档的 ID。</td></tr><tr><td>Binary Data</td><td>二进制数据。用于存储二进制数据。</td></tr><tr><td>Code</td><td>代码类型。用于在文档中存储 JavaScript 代码。</td></tr><tr><td>Regular expression</td><td>正则表达式类型。用于存储正则表达式。</td></tr></tbody></table><h3 id="MongoDB-创建数据库"><a href="#MongoDB-创建数据库" class="headerlink" title="MongoDB 创建数据库"></a>MongoDB 创建数据库</h3><p>MongoDB 创建数据库的语法格式如下:</p><pre class="language-none"><code class="language-none">use DATABASE_NAME</code></pre><p>如果数据库不存在,则创建数据库,否则切换到指定数据库。</p><p>数据库名可以是满足以下条件的任意UTF-8字符串。</p><p>· 不能是空字符串(””)。</p><p>· 不得含有’ ‘(空格)、.、$、/、\和\0 (空字符)。</p><p>· 应全部小写。</p><p>· 最多64字节。</p><p>有一些数据库名是保留的:admin, local, config等。可以直接访问这些有特殊作用的数据库。</p><h3 id="MongoDB-删除数据库"><a href="#MongoDB-删除数据库" class="headerlink" title="MongoDB 删除数据库"></a>MongoDB 删除数据库</h3><p>MongoDB 删除数据库的语法格式如下:</p><pre class="language-none"><code class="language-none">db.dropDatabase()</code></pre><p>删除当前数据库,默认为 test,你可以使用 db 命令查看当前数据库名。</p><h3 id="MongoDB-创建集合"><a href="#MongoDB-创建集合" class="headerlink" title="MongoDB 创建集合"></a><a href="https://www.runoob.com/mongodb/mongodb-create-collection.html">MongoDB 创建集合</a></h3><p>MongoDB 中使用 <em><strong>*createCollection()*</strong></em> 方法来创建集合。</p><p>语法格式:</p><pre class="language-none"><code class="language-none">db.createCollection(name, options)</code></pre><p>参数说明:</p><p>· name: 要创建的集合名称</p><p>· options: 可选参数, 指定有关内存大小及索引的选项</p><h3 id="MongoDB-删除集合"><a href="#MongoDB-删除集合" class="headerlink" title="MongoDB 删除集合"></a>MongoDB 删除集合</h3><p>MongoDB 中使用 drop() 方法来删除集合。</p><p><em><strong>*语法格式:*</strong></em></p><pre class="language-none"><code class="language-none">db.collection.drop()</code></pre><p><em><strong>*返回值*</strong></em></p><p>如果成功删除选定集合,则 drop() 方法返回 true,否则返回 false。</p><p>以下实例删除了 runoob 数据库中的集合 site:</p><pre class="language-none"><code class="language-none">> use runoobswitched to db runoob> db.createCollection("runoob") # 先创建集合,类似数据库中的表> show tables # show collections 命令会更加准确点runoob> db.runoob.drop()true> show tables> </code></pre><h3 id="插入文档"><a href="#插入文档" class="headerlink" title="插入文档"></a>插入文档</h3><p>文档的数据结构和JSON基本一样。</p><p>所有存储在集合中的数据都是BSON格式。</p><p>BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON。</p><p>MongoDB 使用 insert() 或 save() 方法向集合中插入文档,语法如下:</p><pre class="language-none"><code class="language-none">db.COLLECTION_NAME.insert(document)</code></pre><p>以下文档可以存储在 MongoDB 的 books数据库 的 col 集合中:</p><pre class="language-none"><code class="language-none">db.col.insert({title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库', tags: ['mongodb', 'database', 'NoSQL'], likes: 100})</code></pre><h3 id="MongoDB-查询文档"><a href="#MongoDB-查询文档" class="headerlink" title="MongoDB 查询文档"></a><a href="https://www.runoob.com/mongodb/mongodb-query.html">MongoDB 查询文档</a></h3><p>MongoDB 查询文档使用 find() 方法。</p><p>find() 方法以非结构化的方式来显示所有文档。</p><h4 id="语法"><a href="#语法" class="headerlink" title="语法"></a>语法</h4><p>MongoDB 查询数据的语法格式如下:</p><pre class="language-none"><code class="language-none">db.collection.find(query, projection)</code></pre><h3 id="MongoDB-更新文档"><a href="#MongoDB-更新文档" class="headerlink" title="MongoDB 更新文档"></a>MongoDB 更新文档</h3><p>MongoDB 使用 <em><strong>*update()*</strong></em> 和 <em><strong>*save()*</strong></em> 方法来更新集合中的文档。</p><h3 id="update-方法"><a href="#update-方法" class="headerlink" title="update() 方法"></a>update() 方法</h3><p>update() 方法用于更新已存在的文档。语法格式如下:</p><pre class="language-none"><code class="language-none">db.collection.update( <query>, <update>, { upsert: <boolean>, multi: <boolean>, writeConcern: <document> })</code></pre><p><em><strong>*参数说明:*</strong></em></p><p><strong>·</strong> <em><strong>*query*</strong></em> : update的查询条件,类似sql update查询内where后面的。</p><p><strong>·</strong> <em><strong>*update*</strong></em> : update的对象和一些更新的操作符(如$,$inc…)等,也可以理解为sql update查询内set后面的</p><p><strong>·</strong> <em><strong>*upsert*</strong></em> : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。</p><p><strong>·</strong> <em><strong>*multi*</strong></em> : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。</p><p><strong>·</strong> <em><strong>*writeConcern*</strong></em> :可选,抛出异常的级别。</p><p>db.col.update({‘title’:’MongoDB 教程’},{$set:{‘title’:’MongoDB’}})</p><p>以上语句只会修改第一条发现的文档,如果你要修改多条相同的文档,则需要设置 multi 参数为 true。</p><p>db.col.update({‘title’:’MongoDB 教程’},{$set:{‘title’:’MongoDB’}},{multi:true})</p><h3 id="MongoDB-删除文档"><a href="#MongoDB-删除文档" class="headerlink" title="MongoDB 删除文档"></a>MongoDB 删除文档</h3><p>MongoDB remove()函数是用来移除集合中的数据。</p><p>remove() 方法的基本语法格式如下所示:</p><pre class="language-none"><code class="language-none">db.collection.remove(<query>,{justOne: <boolean>,writeConcern: <document>})</code></pre><p><em><strong>*参数说明:*</strong></em></p><p><strong>·</strong> <em><strong>*query*</strong></em> :(可选)删除的文档的条件。</p><p><strong>·</strong> <em><strong>*justOne*</strong></em> : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。</p><p><strong>·</strong> <em><strong>*writeConcern*</strong></em> :(可选)抛出异常的级别。</p><p>db.col.remove({‘title’:’MongoDB 教程’}) WriteResult({ “nRemoved” : 2 }) # 删除了两条数据</p><p>>db.col.find()…… # 没有数据</p><p>如果你只想删除第一条找到的记录可以设置 justOne 为 1,如下所示:</p><p>>db.COLLECTION_NAME.remove(DELETION_CRITERIA,1)</p><p>果你想删除所有数据,可以使用以下方式(类似常规 SQL 的 truncate 命令):</p><p>>db.col.remove({})</p><h3 id="Robo-3T-的使用…"><a href="#Robo-3T-的使用…" class="headerlink" title="Robo 3T 的使用…"></a>Robo 3T 的使用…</h3><h2 id="Mongoose"><a href="#Mongoose" class="headerlink" title="Mongoose"></a>Mongoose</h2><h3 id="mongoose模块"><a href="#mongoose模块" class="headerlink" title="mongoose模块"></a>mongoose模块</h3><p>Node.js<code>连接</code>MongoDB<code>数据库,推荐</code>Mongoose`模块,可以更加方便的对数据库进行操作。</p><h3 id="Node-js中安装模块"><a href="#Node-js中安装模块" class="headerlink" title="Node.js中安装模块"></a>Node.js中安装模块</h3><pre class="language-none"><code class="language-none">npm install mongoose --save</code></pre><h3 id="引入模块"><a href="#引入模块" class="headerlink" title="引入模块"></a>引入模块</h3><p>在需要使用的js文件中引入模块。</p><pre class="language-none"><code class="language-none">var mongoose = require('mongoose');</code></pre><h3 id="连接数据库"><a href="#连接数据库" class="headerlink" title="连接数据库"></a>连接数据库</h3><pre class="language-none"><code class="language-none">var db = mongoose.connect('mongodb://localhost/mongodb',{ useNewUrlParser: true, useUnifiedTopology: true});</code></pre><p>URL以<code>mongodb://[用户名:密码@]数据库地址[:端口]/数据库名</code>。(默认端口27017)</p><p>需要对连接状况进行判断,可以用以下代码:</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> db <span class="token operator">=</span> mongoose<span class="token punctuation">.</span>connection<span class="token punctuation">;</span>db<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">"error"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"数据库连接失败:"</span> <span class="token operator">+</span> error<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>db<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">"open"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"数据库连接成功"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>db<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'disconnected'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'数据库连接断开'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span></code></pre><h3 id="基本概念"><a href="#基本概念" class="headerlink" title="基本概念"></a>基本概念</h3><p>最常接触到的有两个概念<code>Schema</code>、<code>Model</code></p><h4 id="Schema"><a href="#Schema" class="headerlink" title="Schema"></a>Schema</h4><p>在 Mongoose 中,所有数据都由一个 Schema 开始创建。每一个 schema 都映射到一个 Mongodb 的集合(collection),并定义了该集合(collection)中的文档(document)的形式。但不能通过Schema对数据进行更改。</p><pre class="language-tsx" data-language="tsx"><code class="language-tsx"><span class="token keyword">const</span> mongoose <span class="token operator">=</span> <span class="token keyword">require</span><span class="token punctuation">(</span><span class="token string">'mongoose'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">const</span> Schema <span class="token operator">=</span> mongoose<span class="token punctuation">.</span>Schema<span class="token punctuation">;</span><span class="token keyword">const</span> UserShema <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Schema</span><span class="token punctuation">(</span><span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token punctuation">{</span> type<span class="token operator">:</span> String<span class="token punctuation">,</span> required<span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> createTime<span class="token operator">:</span> <span class="token punctuation">{</span> type<span class="token operator">:</span> Date<span class="token punctuation">,</span> <span class="token keyword">default</span><span class="token operator">:</span> Date<span class="token punctuation">.</span>now <span class="token punctuation">}</span><span class="token punctuation">,</span> sex<span class="token operator">:</span> String<span class="token punctuation">,</span> avatar<span class="token operator">:</span> String<span class="token punctuation">,</span> vip<span class="token operator">:</span> Boolean<span class="token punctuation">,</span><span class="token punctuation">}</span><span class="token punctuation">)</span> </code></pre><p><code>Model</code>是将Schema定义的结构赋予集合名。可用此名对数据库进行增删查改。</p><h4 id="Model"><a href="#Model" class="headerlink" title="Model"></a>Model</h4><pre class="language-jsx" data-language="jsx"><code class="language-jsx"><span class="token keyword">var</span> blogModel <span class="token operator">=</span> mongoose<span class="token punctuation">.</span><span class="token function">model</span><span class="token punctuation">(</span><span class="token string">'集合名'</span><span class="token punctuation">,</span> 自定义Schema<span class="token operator">/</span>UserShema<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> blogModel <span class="token operator">=</span> mongoose<span class="token punctuation">.</span><span class="token function">model</span><span class="token punctuation">(</span><span class="token string">'Blog'</span><span class="token punctuation">,</span> blogSchema<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>将名为blogSchema的Schema与Blog名字绑定,即是存入集合的名字,但存入集合的名字是Blogs,会自动添加一个s。<br>这里将Model命名为blogModel,需要对Blog集合操作的话,都需要使用变量名blogModel。</p><h3 id="增查改删-CRUD"><a href="#增查改删-CRUD" class="headerlink" title="增查改删(CRUD)"></a>增查改删(CRUD)</h3><p>所有的参数都是以<code>JSON对象</code>形式传入。</p><h4 id="增-C"><a href="#增-C" class="headerlink" title="增(C)"></a>增(C)</h4><p><code>Model.create(doc(s), [callback])</code></p><p><code>Model#save([options], [options.safe], [options.validateBeforeSave], [fn])</code></p><p><code>Model.insertMany(doc(s), [options], [callback])</code></p><h4 id="查-R"><a href="#查-R" class="headerlink" title="查(R)"></a>查(R)</h4><p><code>Model.find(conditions, [projection], [options], [callback])</code></p><p><code>Model.findOne([conditions], [projection], [options], [callback])</code></p><p><code>Model.findById(id, [projection], [options], [callback])</code></p><h4 id="改-U"><a href="#改-U" class="headerlink" title="改(U)"></a>改(U)</h4><p><code>Model.update(conditions, doc, [options], [callback])</code></p><p><code>Model.updateMany(conditions, doc, [options], [callback])</code></p><p><code>Model.updateOne(conditions, doc, [options], [callback])</code></p><h4 id="删-D"><a href="#删-D" class="headerlink" title="删(D)"></a>删(D)</h4><p><code>Model.remove(conditions, [callback])</code></p><p><code>Model.deleteMany(conditions, [callback])</code></p><p><code>Model.deleteOne(conditions, [callback])</code></p><h4 id="相关手册"><a href="#相关手册" class="headerlink" title="相关手册"></a>相关手册</h4><p>1.菜鸟教程:<a href="https://www.runoob.com/mongodb/mongodb-sort.html">https://www.runoob.com/mongodb/mongodb-sort.html</a></p><p>2.mongoose:<a href="http://www.mongoosejs.net/docs/index.html">http://www.mongoosejs.net/docs/index.html</a></p>]]></content>
<categories>
<category> 学习笔记 </category>
</categories>
<tags>
<tag> node </tag>
</tags>
</entry>
<entry>
<title>关于JS和时间相关的函数</title>
<link href="/2021/12/11/JS-time/"/>
<url>/2021/12/11/JS-time/</url>
<content type="html"><![CDATA[<h2 id="获取当前时间"><a href="#获取当前时间" class="headerlink" title="获取当前时间"></a>获取当前时间</h2><blockquote><p>得到当前时间的 YYYY-MM-DD HH:MI:ss 格式</p></blockquote><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">nowtime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">var</span> _this <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> yy <span class="token operator">=</span> _this<span class="token punctuation">.</span><span class="token function">getFullYear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> mm <span class="token operator">=</span> _this<span class="token punctuation">.</span><span class="token function">getMonth</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token number">1</span><span class="token operator"><</span><span class="token number">10</span><span class="token operator">?</span><span class="token string">'0'</span><span class="token operator">+</span><span class="token punctuation">(</span>_this<span class="token punctuation">.</span><span class="token function">getMonth</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token punctuation">(</span>_this<span class="token punctuation">.</span><span class="token function">getMonth</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> dd <span class="token operator">=</span> _this<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator"><</span><span class="token number">10</span><span class="token operator">?</span><span class="token string">'0'</span><span class="token operator">+</span>_this<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> _this<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> hh <span class="token operator">=</span> _this<span class="token punctuation">.</span><span class="token function">getHours</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator"><</span> <span class="token number">10</span> <span class="token operator">?</span> <span class="token string">'0'</span> <span class="token operator">+</span> _this<span class="token punctuation">.</span><span class="token function">getHours</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> _this<span class="token punctuation">.</span><span class="token function">getHours</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> mf <span class="token operator">=</span> _this<span class="token punctuation">.</span><span class="token function">getMinutes</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator"><</span> <span class="token number">10</span> <span class="token operator">?</span> <span class="token string">'0'</span> <span class="token operator">+</span> _this<span class="token punctuation">.</span><span class="token function">getMinutes</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> _this<span class="token punctuation">.</span><span class="token function">getMinutes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> ss <span class="token operator">=</span> _this<span class="token punctuation">.</span><span class="token function">getSeconds</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator"><</span> <span class="token number">10</span> <span class="token operator">?</span> <span class="token string">'0'</span> <span class="token operator">+</span> _this<span class="token punctuation">.</span><span class="token function">getSeconds</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> _this<span class="token punctuation">.</span><span class="token function">getSeconds</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> nowtime <span class="token operator">=</span> yy <span class="token operator">+</span> <span class="token string">'-'</span> <span class="token operator">+</span> mm <span class="token operator">+</span> <span class="token string">'-'</span> <span class="token operator">+</span> dd <span class="token operator">+</span> <span class="token string">' '</span> <span class="token operator">+</span> hh <span class="token operator">+</span> <span class="token string">':'</span> <span class="token operator">+</span> mf <span class="token operator">+</span> <span class="token string">':'</span> <span class="token operator">+</span> ss<span class="token punctuation">;</span> <span class="token keyword">return</span> nowtime<span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><span id="more"></span><h2 id="计算时间差"><a href="#计算时间差" class="headerlink" title="计算时间差"></a>计算时间差</h2><h3 id="相差的天-小时-分钟-秒"><a href="#相差的天-小时-分钟-秒" class="headerlink" title="相差的天-小时-分钟-秒"></a>相差的天-小时-分钟-秒</h3><blockquote><p>传入时间格式YYYY-MM-DD HH:MI:ss 得到两个时间相差的 年-月-天-小时-分钟-秒</p><p>传入时间格式YYYY-MM-DD 得到两个时间相差的 年月日</p></blockquote><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">difftime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">var</span> new_date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//格式化日期,不传默认当前时间</span><span class="token keyword">var</span> old_date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token string">'2021-12-09 11:11:11'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> difftime <span class="token operator">=</span> <span class="token punctuation">(</span>new_date <span class="token operator">-</span> old_date<span class="token punctuation">)</span><span class="token operator">/</span><span class="token number">1000</span><span class="token punctuation">;</span> <span class="token comment">//计算时间差,并把毫秒转换成秒</span> <span class="token keyword">var</span> year <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span>difftime <span class="token operator">/</span> <span class="token number">86400</span> <span class="token operator">/</span> <span class="token number">365</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//年</span> <span class="token keyword">var</span> month <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span>difftime<span class="token operator">/</span> <span class="token number">86400</span> <span class="token operator">/</span> <span class="token number">30</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//月</span><span class="token keyword">var</span> days <span class="token operator">=</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>difftime<span class="token operator">/</span><span class="token number">86400</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 天 24*60*60*1000 </span><span class="token keyword">var</span> hours <span class="token operator">=</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>difftime<span class="token operator">/</span><span class="token number">3600</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token number">24</span><span class="token operator">*</span>days<span class="token punctuation">;</span> <span class="token comment">// 小时 60*60 总小时数-过去的小时数=现在的小时数 </span><span class="token keyword">var</span> minutes <span class="token operator">=</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>difftime<span class="token operator">%</span><span class="token number">3600</span><span class="token operator">/</span><span class="token number">60</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 分钟 -(day*24) 以60秒为一整份 取余 剩下秒数 秒数/60 就是分钟数</span><span class="token keyword">var</span> seconds <span class="token operator">=</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>difftime<span class="token operator">%</span><span class="token number">60</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 以60秒为一整份 取余 剩下秒数</span><span class="token keyword">var</span> difftimes <span class="token operator">=</span> year<span class="token operator">+</span><span class="token string">"年,"</span><span class="token operator">+</span>month<span class="token operator">+</span><span class="token string">"月,"</span><span class="token operator">+</span> days<span class="token operator">+</span><span class="token string">"天, "</span><span class="token operator">+</span>hours<span class="token operator">+</span><span class="token string">"小时, "</span><span class="token operator">+</span>minutes<span class="token operator">+</span><span class="token string">"分钟, "</span><span class="token operator">+</span>seconds<span class="token operator">+</span><span class="token string">"秒"</span><span class="token punctuation">;</span><span class="token keyword">return</span> difftimes<span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><h3 id="相差的分钟"><a href="#相差的分钟" class="headerlink" title="相差的分钟"></a>相差的分钟</h3><blockquote><p>传入的时间格式 HH:mi</p><p>得到相差的分钟数</p></blockquote><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">timeDifference</span><span class="token punctuation">(</span><span class="token parameter">startTime<span class="token punctuation">,</span>endTime</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">var</span> start1<span class="token operator">=</span>startTime<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">":"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> startAll<span class="token operator">=</span><span class="token function">parseInt</span><span class="token punctuation">(</span>start1<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token operator">*</span><span class="token number">60</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token function">parseInt</span><span class="token punctuation">(</span>start1<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> end1<span class="token operator">=</span>endTime<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">":"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> endAll<span class="token operator">=</span><span class="token function">parseInt</span><span class="token punctuation">(</span>end1<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token operator">*</span><span class="token number">60</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token function">parseInt</span><span class="token punctuation">(</span>end1<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> endAll<span class="token operator">-</span>startAll<span class="token punctuation">;</span><span class="token punctuation">}</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">timeDifference</span><span class="token punctuation">(</span><span class="token string">"08:30"</span><span class="token punctuation">,</span><span class="token string">"10:30"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">////120</span></code></pre><h2 id="获取指定日期的前后N天"><a href="#获取指定日期的前后N天" class="headerlink" title="获取指定日期的前后N天"></a>获取指定日期的前后N天</h2><blockquote><p>传入时间格式 date: YYYY-MM-DD ;day:负数为前N天,正数为后N天</p><p>得到date的 前后day天</p></blockquote><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">getNextDate</span><span class="token punctuation">(</span><span class="token parameter">date<span class="token punctuation">,</span> day</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">var</span> dd <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span>dd<span class="token punctuation">.</span><span class="token function">setDate</span><span class="token punctuation">(</span>dd<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> day<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> y <span class="token operator">=</span> dd<span class="token punctuation">.</span><span class="token function">getFullYear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> m <span class="token operator">=</span> dd<span class="token punctuation">.</span><span class="token function">getMonth</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span> <span class="token operator"><</span> <span class="token number">10</span> <span class="token operator">?</span> <span class="token string">"0"</span> <span class="token operator">+</span> <span class="token punctuation">(</span>dd<span class="token punctuation">.</span><span class="token function">getMonth</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">:</span> dd<span class="token punctuation">.</span><span class="token function">getMonth</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">var</span> d <span class="token operator">=</span> dd<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator"><</span> <span class="token number">10</span> <span class="token operator">?</span> <span class="token string">"0"</span> <span class="token operator">+</span> dd<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> dd<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> y <span class="token operator">+</span> <span class="token string">"-"</span> <span class="token operator">+</span> m <span class="token operator">+</span> <span class="token string">"-"</span> <span class="token operator">+</span> d<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">getNextDate</span><span class="token punctuation">(</span><span class="token string">"2020-01-01"</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment">////2019-12-31</span></code></pre><h2 id="获取指定日期的前后N个月"><a href="#获取指定日期的前后N个月" class="headerlink" title="获取指定日期的前后N个月"></a>获取指定日期的前后N个月</h2><blockquote><p>传入时间格式 date:YYYY-MM-DD ; monthNum:负数为前N月,正数为后N月</p><p>得到date的 前后monthNum月</p></blockquote><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">GetPreMonthDay</span><span class="token punctuation">(</span><span class="token parameter">date<span class="token punctuation">,</span> monthNum</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">var</span> dateArr <span class="token operator">=</span> date<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">'-'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> year <span class="token operator">=</span> dateArr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">//获取当前日期的年份</span><span class="token keyword">var</span> month <span class="token operator">=</span> dateArr<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">//获取当前日期的月份</span><span class="token keyword">var</span> day <span class="token operator">=</span> dateArr<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">//获取当前日期的日</span><span class="token keyword">var</span> days <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>year<span class="token punctuation">,</span> month<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>days <span class="token operator">=</span> days<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//获取当前日期中月的天数</span><span class="token keyword">var</span> year2 <span class="token operator">=</span> year<span class="token punctuation">;</span><span class="token keyword">var</span> month2 <span class="token operator">=</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>month<span class="token punctuation">)</span> <span class="token operator">+</span> monthNum<span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>month2 <span class="token operator"><=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>year2 <span class="token operator">=</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>year2<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>month2 <span class="token operator">/</span> <span class="token number">12</span> <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">?</span> <span class="token number">1</span> <span class="token operator">:</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>month2<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">12</span><span class="token punctuation">)</span><span class="token punctuation">;</span>month2 <span class="token operator">=</span> <span class="token number">12</span> <span class="token operator">-</span> <span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">abs</span><span class="token punctuation">(</span>month2<span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">12</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">if</span> <span class="token punctuation">(</span>month2 <span class="token operator">></span> <span class="token number">12</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>year2 <span class="token operator">=</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>year2<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>month2 <span class="token operator">/</span> <span class="token number">12</span> <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">?</span> <span class="token number">1</span> <span class="token operator">:</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>month2<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">12</span><span class="token punctuation">)</span><span class="token punctuation">;</span>month2 <span class="token operator">=</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>month2 <span class="token operator">%</span> <span class="token number">12</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">var</span> day2 <span class="token operator">=</span> day<span class="token punctuation">;</span><span class="token keyword">var</span> days2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>year2<span class="token punctuation">,</span> month2<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>days2 <span class="token operator">=</span> days2<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>day2 <span class="token operator">></span> days2<span class="token punctuation">)</span> <span class="token punctuation">{</span>day2 <span class="token operator">=</span> days2<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">if</span> <span class="token punctuation">(</span>month2 <span class="token operator"><</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>month2 <span class="token operator">=</span> <span class="token string">'0'</span> <span class="token operator">+</span> month2<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">var</span> t2 <span class="token operator">=</span> year2 <span class="token operator">+</span> <span class="token string">'-'</span> <span class="token operator">+</span> month2 <span class="token operator">+</span> <span class="token string">'-'</span> <span class="token operator">+</span> day2<span class="token punctuation">;</span><span class="token keyword">return</span> t2<span class="token punctuation">;</span><span class="token punctuation">}</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">GetPreMonthDay</span><span class="token punctuation">(</span><span class="token string">"2020-01-01"</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment">////2019-12-01</span></code></pre><h2 id="计算指定日期为周几"><a href="#计算指定日期为周几" class="headerlink" title="计算指定日期为周几"></a>计算指定日期为周几</h2><blockquote><p>传入时间格式 YYYY-MM-DD</p></blockquote><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">getWeek</span><span class="token punctuation">(</span><span class="token parameter">dateString</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> dateArray <span class="token operator">=</span> dateString<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">"-"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>dateArray<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>dateArray<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> dateArray<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token string">"周"</span> <span class="token operator">+</span> <span class="token string">"日一二三四五六"</span><span class="token punctuation">.</span><span class="token function">charAt</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getDay</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">getWeek</span><span class="token punctuation">(</span><span class="token string">'2021-12-09'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment">////周四</span></code></pre><h2 id="判断多个时间段是否有重复"><a href="#判断多个时间段是否有重复" class="headerlink" title="判断多个时间段是否有重复"></a>判断多个时间段是否有重复</h2><blockquote><p>将时间段按数组对象传入;这里只判断的是时分秒</p><p>s:开始时间 e:结束时间</p></blockquote><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> dateArr <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> s<span class="token operator">:</span> <span class="token string">'01:00:00'</span><span class="token punctuation">,</span> e<span class="token operator">:</span> <span class="token string">'14:30:00'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> s<span class="token operator">:</span> <span class="token string">'14:20:00'</span><span class="token punctuation">,</span> e<span class="token operator">:</span> <span class="token string">'15:05:00'</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token keyword">function</span> <span class="token function">judege</span><span class="token punctuation">(</span><span class="token parameter">idx</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> k <span class="token keyword">in</span> dateArr<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">if</span> <span class="token punctuation">(</span>idx <span class="token operator">!==</span> k<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">if</span> <span class="token punctuation">(</span>dateArr<span class="token punctuation">[</span>k<span class="token punctuation">]</span><span class="token punctuation">.</span>s <span class="token operator"><=</span> dateArr<span class="token punctuation">[</span>idx<span class="token punctuation">]</span><span class="token punctuation">.</span>s <span class="token operator">&&</span> dateArr<span class="token punctuation">[</span>k<span class="token punctuation">]</span><span class="token punctuation">.</span>e <span class="token operator">></span> dateArr<span class="token punctuation">[</span>idx<span class="token punctuation">]</span><span class="token punctuation">.</span>s<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">}</span><span class="token keyword">if</span> <span class="token punctuation">(</span>dateArr<span class="token punctuation">[</span>k<span class="token punctuation">]</span><span class="token punctuation">.</span>s <span class="token operator"><</span> dateArr<span class="token punctuation">[</span>idx<span class="token punctuation">]</span><span class="token punctuation">.</span>e <span class="token operator">&&</span> dateArr<span class="token punctuation">[</span>k<span class="token punctuation">]</span><span class="token punctuation">.</span>e <span class="token operator">>=</span> dateArr<span class="token punctuation">[</span>idx<span class="token punctuation">]</span><span class="token punctuation">.</span>e<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">Fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> k <span class="token keyword">in</span> dateArr<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">judege</span><span class="token punctuation">(</span>k<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">}</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token comment">//true的话表示没有重叠,false表示有重叠</span></code></pre><div class="success"><blockquote><p>这里使用了<code>for...in</code>循环;</p><p><strong>for…in 语句用于遍历数组或者对象的属性</strong></p></blockquote></div><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> obj<span class="token operator">=</span><span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token string">'小明'</span><span class="token punctuation">,</span>age<span class="token operator">:</span><span class="token number">12</span><span class="token punctuation">}</span><span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">var</span> k <span class="token keyword">in</span> obj<span class="token punctuation">)</span><span class="token punctuation">{</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>k<span class="token punctuation">)</span> <span class="token comment">///name age</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">[</span>k<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token comment">///小明 12</span><span class="token punctuation">}</span><span class="token keyword">var</span> arr<span class="token operator">=</span><span class="token punctuation">[</span><span class="token string">'小明'</span><span class="token punctuation">,</span><span class="token string">'小花'</span><span class="token punctuation">,</span><span class="token string">'小林'</span><span class="token punctuation">]</span><span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">var</span> k <span class="token keyword">in</span> arr<span class="token punctuation">)</span><span class="token punctuation">{</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>k<span class="token punctuation">)</span> <span class="token comment">///0 1 2</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span>k<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token comment">///小明 小花 小林</span><span class="token punctuation">}</span><span class="token keyword">var</span> arrobj<span class="token operator">=</span><span class="token punctuation">[</span><span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token string">'小明'</span><span class="token punctuation">,</span>age<span class="token operator">:</span><span class="token number">12</span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token string">'小花'</span><span class="token punctuation">,</span>age<span class="token operator">:</span><span class="token number">15</span><span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">var</span> k <span class="token keyword">in</span> arrobj<span class="token punctuation">)</span><span class="token punctuation">{</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>k<span class="token punctuation">)</span> <span class="token comment">///0 1</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arrobj<span class="token punctuation">[</span>k<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token comment">///{name:'小明',age:12} {name:'小花',age:15}</span><span class="token punctuation">}</span></code></pre><div class="info"><blockquote><p>由此可以看出使用<code>for...in</code> 遍历对象时,k为对象的属性;遍历数组和数组对象时,k为下标</p></blockquote></div><h2 id="倒计时"><a href="#倒计时" class="headerlink" title="倒计时"></a>倒计时</h2><blockquote><p>传入一个固定的结束时间</p></blockquote><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">getEndTime</span><span class="token punctuation">(</span><span class="token parameter">endTime</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">var</span> startDate <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//开始时间,当前时间</span><span class="token keyword">var</span> endDate <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>endTime<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//结束时间,需传入时间参数</span><span class="token keyword">var</span> t <span class="token operator">=</span> endDate<span class="token punctuation">.</span><span class="token function">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> startDate<span class="token punctuation">.</span><span class="token function">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//时间差的毫秒数</span><span class="token keyword">var</span> d <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span>h <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span>m <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span>s <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>t <span class="token operator">>=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>d <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span>t <span class="token operator">/</span> <span class="token number">1000</span> <span class="token operator">/</span> <span class="token number">3600</span> <span class="token operator">/</span> <span class="token number">24</span><span class="token punctuation">)</span><span class="token punctuation">;</span>h <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span>t <span class="token operator">/</span> <span class="token number">1000</span> <span class="token operator">/</span> <span class="token number">60</span> <span class="token operator">/</span> <span class="token number">60</span> <span class="token operator">%</span> <span class="token number">24</span><span class="token punctuation">)</span><span class="token punctuation">;</span>m <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span>t <span class="token operator">/</span> <span class="token number">1000</span> <span class="token operator">/</span> <span class="token number">60</span> <span class="token operator">%</span> <span class="token number">60</span><span class="token punctuation">)</span><span class="token punctuation">;</span>s <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span>t <span class="token operator">/</span> <span class="token number">1000</span> <span class="token operator">%</span> <span class="token number">60</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">return</span> <span class="token punctuation">{</span>d<span class="token operator">:</span>d<span class="token punctuation">,</span>h<span class="token operator">:</span>h<span class="token punctuation">,</span>m<span class="token operator">:</span>m<span class="token punctuation">,</span>s<span class="token operator">:</span>s<span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">var</span> active <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">"active"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> timer <span class="token operator">=</span> <span class="token function">setInterval</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><span class="token keyword">var</span> time <span class="token operator">=</span> <span class="token function">getEndTime</span><span class="token punctuation">(</span><span class="token string">'2021-12-10 12:00:00'</span><span class="token punctuation">)</span><span class="token comment">//此处设置你想要结束的时间</span><span class="token keyword">var</span> endtime <span class="token operator">=</span> <span class="token string">'距离干饭还有:'</span> <span class="token operator">+</span> time<span class="token punctuation">.</span>d <span class="token operator">+</span> <span class="token string">'天'</span> <span class="token operator">+</span> time<span class="token punctuation">.</span>h <span class="token operator">+</span> <span class="token string">'小时'</span> <span class="token operator">+</span> time<span class="token punctuation">.</span>m <span class="token operator">+</span> <span class="token string">'分钟'</span> <span class="token operator">+</span> time<span class="token punctuation">.</span>s <span class="token operator">+</span> <span class="token string">'秒'</span><span class="token punctuation">;</span><span class="token keyword">if</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>d <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">&&</span> time<span class="token punctuation">.</span>h <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">&&</span> time<span class="token punctuation">.</span>m <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">&&</span> time<span class="token punctuation">.</span>s <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token function">clearInterval</span><span class="token punctuation">(</span>timer<span class="token punctuation">)</span><span class="token punctuation">;</span>active<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> <span class="token string">"干饭!!!"</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h2 id="公历农历互转"><a href="#公历农历互转" class="headerlink" title="公历农历互转"></a>公历农历互转</h2><p><a href="https://blog.jjonline.cn/userInterFace/173.html">公历农历互转</a></p><div class="yellow"><blockquote><p>将时间格式为YYYY/MM/DD HH:MI:ss格式替换为YYYY-MM-DD HH:MI:ss</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> str<span class="token operator">=</span><span class="token string">'2021/11/16 13:17:37'</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\/</span><span class="token regex-delimiter">/</span><span class="token regex-flags">g</span></span><span class="token punctuation">,</span><span class="token string">'-'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment">///2021-11-16 13:17:37</span></code></pre></blockquote></div><h2 id="获取指定时间的时间戳"><a href="#获取指定时间的时间戳" class="headerlink" title="获取指定时间的时间戳"></a>获取指定时间的时间戳</h2><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">getTargetTime</span><span class="token punctuation">(</span><span class="token parameter">t</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>t<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span></code></pre><h2 id="时间戳转换为日期"><a href="#时间戳转换为日期" class="headerlink" title="时间戳转换为日期"></a>时间戳转换为日期</h2><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">add0</span><span class="token punctuation">(</span><span class="token parameter">m</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">return</span> m <span class="token operator"><</span> <span class="token number">10</span> <span class="token operator">?</span> <span class="token string">'0'</span> <span class="token operator">+</span> m <span class="token operator">:</span> m<span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">format</span><span class="token punctuation">(</span><span class="token parameter">shijianchuo</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//shijianchuo是整数,否则要parseInt转换</span><span class="token keyword">var</span> time <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>shijianchuo<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> y <span class="token operator">=</span> time<span class="token punctuation">.</span><span class="token function">getFullYear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> m <span class="token operator">=</span> time<span class="token punctuation">.</span><span class="token function">getMonth</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">var</span> d <span class="token operator">=</span> time<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> h <span class="token operator">=</span> time<span class="token punctuation">.</span><span class="token function">getHours</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> mm <span class="token operator">=</span> time<span class="token punctuation">.</span><span class="token function">getMinutes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> s <span class="token operator">=</span> time<span class="token punctuation">.</span><span class="token function">getSeconds</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> y <span class="token operator">+</span> <span class="token string">'-'</span> <span class="token operator">+</span> <span class="token function">add0</span><span class="token punctuation">(</span>m<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">'-'</span> <span class="token operator">+</span> <span class="token function">add0</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">' '</span> <span class="token operator">+</span> <span class="token function">add0</span><span class="token punctuation">(</span>h<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">':'</span> <span class="token operator">+</span> <span class="token function">add0</span><span class="token punctuation">(</span>mm<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">':'</span> <span class="token operator">+</span> <span class="token function">add0</span><span class="token punctuation">(</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre>]]></content>
<categories>
<category> JS </category>
</categories>
<tags>
<tag> 函數 </tag>
</tags>
</entry>
<entry>
<title>Markdown语法</title>
<link href="/2021/12/07/usemd/"/>
<url>/2021/12/07/usemd/</url>
<content type="html"><![CDATA[<div class="info"><blockquote><p>Markdown是一种轻量级标记语言,允许使用易读易写的纯文本格式编写文档,然后转换成有效的XHTML(或者HTML)文档</p></blockquote></div><pre><code>因为Markdown轻量高效,语法简单,因此写博客用此就很方便,下面介绍一些markdown的常用语法。</code></pre><span id="more"></span><h2 id="标题"><a href="#标题" class="headerlink" title="标题"></a>标题</h2><div class="info"><blockquote><p>使用 # 号可表示 1-6 级标题,一级标题对应一个 # 号,二级标题对应两个 # 号,以此类推。</p></blockquote></div><pre class="language-none"><code class="language-none"># 一级标题## 二级标题### 三级标题#### 四级标题##### 五级标题###### 六级标题</code></pre><p>效果:</p><h1 id="一级标题"><a href="#一级标题" class="headerlink" title="一级标题"></a>一级标题</h1><h2 id="二级标题"><a href="#二级标题" class="headerlink" title="二级标题"></a>二级标题</h2><h3 id="三级标题"><a href="#三级标题" class="headerlink" title="三级标题"></a>三级标题</h3><h4 id="四级标题"><a href="#四级标题" class="headerlink" title="四级标题"></a>四级标题</h4><h5 id="五级标题"><a href="#五级标题" class="headerlink" title="五级标题"></a>五级标题</h5><h6 id="六级标题"><a href="#六级标题" class="headerlink" title="六级标题"></a>六级标题</h6><div class="info"><blockquote><p>还可以使用= 和 - 标记一级和二级标题</p></blockquote></div><pre class="language-none"><code class="language-none">一级标题=================二级标题-----------------</code></pre><p>效果:</p><h1 id="一级标题-1"><a href="#一级标题-1" class="headerlink" title="一级标题"></a>一级标题</h1><h2 id="二级标题-1"><a href="#二级标题-1" class="headerlink" title="二级标题"></a>二级标题</h2><h2 id="字体"><a href="#字体" class="headerlink" title="字体"></a>字体</h2><pre class="language-none"><code class="language-none">*斜体文本*_斜体文本_**粗体文本**__粗体文本__***粗斜体文本***___粗斜体文本___</code></pre><p>效果:</p><p><em>斜体文本</em><br><em>斜体文本</em><br><strong>粗体文本</strong><br><strong>粗体文本</strong><br><em><strong>粗斜体文本</strong></em><br><em><strong>粗斜体文本</strong></em></p><h2 id="删除线"><a href="#删除线" class="headerlink" title="删除线"></a>删除线</h2><div class="info"><blockquote><p>在文字的两端加上两个波浪线 ~~</p></blockquote></div><pre class="language-none"><code class="language-none">~~删除线~~</code></pre><p>效果:</p><p><del>删除线</del></p><h2 id="下划线"><a href="#下划线" class="headerlink" title="下划线"></a>下划线</h2><div class="info"><blockquote><pre class="language-none"><code class="language-none">通过 HTML 的<u></u> 标签来实现</code></pre></blockquote></div><pre class="language-none"><code class="language-none"><u>带下划线文本</u></code></pre><p>效果:</p><p><u>带下划线文本</u></p><h2 id="分割线"><a href="#分割线" class="headerlink" title="分割线"></a>分割线</h2><div class="info"><blockquote><p>可以在一行中用三个以上的星号、减号、底线来建立一个分隔线,行内不能有其他东西;也可以在星号或是减号中间插入空格</p></blockquote></div><pre class="language-none"><code class="language-none">**** * ******- - -----------</code></pre><p>效果:</p><hr><hr><hr><hr><hr><h2 id="区块"><a href="#区块" class="headerlink" title="区块"></a>区块</h2><div class="info"><blockquote><p>区块引用是在段落开头使用 > 符号 ,然后后面紧跟一个空格符号</p></blockquote></div><pre class="language-none"><code class="language-none">> 区块</code></pre><p>效果:</p><blockquote><p>区块</p></blockquote><div class="info"><blockquote><p>区块嵌套:一个 > 符号是最外层,两个 > 符号是第一层嵌套,以此类推</p></blockquote></div><pre class="language-none"><code class="language-none">> 最外层> > 第一层嵌套> > > 第二层嵌套</code></pre><blockquote><p>最外层</p><blockquote><p>第一层嵌套</p><blockquote><p>第二层嵌套</p></blockquote></blockquote></blockquote><h2 id="链接"><a href="#链接" class="headerlink" title="链接"></a>链接</h2><pre class="language-none"><code class="language-none">[链接名称](链接地址)或者<链接地址></code></pre><p>效果:</p><p><a href="https://wangyou.ink/">忘忧的小站</a></p><p>或者</p><p><a href="https://wangyou.ink/">https://wangyou.ink</a></p><h2 id="图片"><a href="#图片" class="headerlink" title="图片"></a>图片</h2><div class="info"><blockquote><p>开头一个感叹号 !<br>接着一个方括号,里面放上图片的替代文字<br>接着一个普通括号,里面放上图片的网址,最后还可以用引号包住并加上选择性的 ‘title’ 属性的文字。</p></blockquote></div><pre class="language-none"><code class="language-none">![alt 属性文本](图片地址)![alt 属性文本](图片地址 "可选标题")</code></pre><p>效果:</p><p><img src="https://img.wenhairu.com/images/2021/12/05/pq6ZA.jpg" alt="wangyou 一个图片" title="慢慢" loading="lazy"></p><div class="info"><blockquote><p>如果想指定图片的宽高,可以直接插入img标签</p></blockquote></div><pre class="language-none"><code class="language-none"><img src='https://img.wenhairu.com/images/2021/12/05/pq6ZA.jpg' width='30%' /></code></pre><h2 id="表格"><a href="#表格" class="headerlink" title="表格"></a>表格</h2><div class="info"><blockquote><p>制作表格使用 | 来分隔不同的单元格,使用 - 来分隔表头和其他行</p></blockquote></div><pre class="language-none"><code class="language-none">| 表头 | 表头 || ---- | ---- || 单元格 | 单元格 || 单元格 | 单元格 |</code></pre><p>效果:</p><table><thead><tr><th>表头</th><th>表头</th></tr></thead><tbody><tr><td>单元格</td><td>单元格</td></tr><tr><td>单元格</td><td>单元格</td></tr></tbody></table><div class="info"><blockquote><p>表格支持设置对齐方式<br>-: 设置内容和标题栏居右对齐<br>:- 设置内容和标题栏居左对齐<br>:-: 设置内容和标题栏居中对齐</p></blockquote></div><pre class="language-none"><code class="language-none">| 左对齐 | 右对齐 | 居中对齐 || :-----| ----: | :----: || 单元格 | 单元格 | 单元格 || 单元格 | 单元格 | 单元格 |</code></pre><p>效果:</p><table><thead><tr><th align="left">左对齐</th><th align="right">右对齐</th><th align="center">居中对齐</th></tr></thead><tbody><tr><td align="left">单元格</td><td align="right">单元格</td><td align="center">单元格</td></tr><tr><td align="left">单元格</td><td align="right">单元格</td><td align="center">单元格</td></tr></tbody></table><h2 id="流程图"><a href="#流程图" class="headerlink" title="流程图"></a>流程图</h2><div class="warning"><blockquote><p>可将以下代码复制到markdown编辑器中查看效果</p></blockquote></div><div class="info"><blockquote><p>横向流程图源码格式</p></blockquote></div><pre class="language-none"><code class="language-none">```mermaidgraph LRA[方形] -->B(圆角) B --> C{条件a} C -->|a=1| D[结果1] C -->|a=2| E[结果2] F[横向流程图]```</code></pre><div class="info"><blockquote><p>竖向流程图源码格式</p></blockquote></div><pre class="language-none"><code class="language-none">```mermaidgraph TDA[方形] --> B(圆角) B --> C{条件a} C --> |a=1| D[结果1] C --> |a=2| E[结果2] F[竖向流程图]```</code></pre><div class="info"><blockquote><p>标准流程图源码格式</p></blockquote></div><pre class="language-none"><code class="language-none">```flowst=>start: 开始框op=>operation: 处理框cond=>condition: 判断框(是或否?)sub1=>subroutine: 子流程io=>inputoutput: 输入输出框e=>end: 结束框st->op->condcond(yes)->io->econd(no)->sub1(right)->op```</code></pre>]]></content>
<categories>
<category> 教程 </category>
</categories>
<tags>
<tag> markdown </tag>
</tags>
</entry>
<entry>
<title>正则</title>
<link href="/2021/12/04/grep/"/>
<url>/2021/12/04/grep/</url>
<content type="html"><![CDATA[<img src="https://img.wenhairu.com/images/2021/12/01/1xlgS.jpg" width="100%" loading="lazy"><p>正则表达式是一个描述字符模式的对象。也就是把规则说给计算机听。javascript中的RegExp类表示正则表达式。</p><p>可以使用RegExp()构造函数来创建RegExp对象,也可以通过直接量与法来创建。</p><span id="more"></span><h2 id="语法"><a href="#语法" class="headerlink" title="语法"></a>语法</h2><h3 id="构造函数:"><a href="#构造函数:" class="headerlink" title="构造函数:"></a>构造函数:</h3><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> reg <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">RegExp</span><span class="token punctuation">(</span>表达式,修饰符<span class="token punctuation">)</span>;</code></pre><h3 id="字面量:"><a href="#字面量:" class="headerlink" title="字面量:"></a>字面量:</h3><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> reg <span class="token operator">=</span> <span class="token operator">/</span>表达式<span class="token operator">/</span>修饰符;</code></pre><h2 id="常用修饰符"><a href="#常用修饰符" class="headerlink" title="常用修饰符"></a>常用修饰符</h2><table><thead><tr><th>i</th><th>不区分大小写</th></tr></thead><tbody><tr><td>g</td><td>全局匹配</td></tr><tr><td>m</td><td>多行匹配</td></tr><tr><td>s</td><td>特殊字符圆点 <strong>.</strong> 中包含换行符 \n</td></tr></tbody></table><h2 id="常用的元字符(特殊字符,注意大小写"><a href="#常用的元字符(特殊字符,注意大小写" class="headerlink" title="常用的元字符(特殊字符,注意大小写)"></a>常用的元字符(特殊字符,注意大小写)</h2> <table> <tr> <td>^</td> <td>开始字符</td> </tr> <tr> <td>$</td> <td>结束字符</td> </tr> <tr> <td>\</td> <td>转义符>>特殊标点符号,在前面加 \ 后,就代表该符号本身.^ 要匹配 "^" 字符本身,请使用 \^ 特殊标点符号() [ ] { } . ? + * |</td> </tr> <tr> <td>\w</td> <td>匹配字母、数字、下划线</td> </tr> <tr> <td>\W</td> <td>匹配非字母、数字、下划线</td> </tr> <tr> <td>\d</td> <td>匹配数字</td> </tr> <tr> <td>\D</td> <td>匹配非数字 </td> </tr> <tr> <td>\s</td> <td>匹配空自字符(空格、换行)</td> </tr> <tr> <td>\S</td> <td>匹配非空白字符</td> </tr> <tr> <td>\n</td> <td>匹配换行符</td> </tr> </table><h2 id="常用限定符"><a href="#常用限定符" class="headerlink" title="常用限定符"></a>常用限定符</h2> <table> <tr> <td>*</td> <td>匹配前面的子表达式零次或多次</td> </tr> <tr> <td>+</td> <td>匹配前面的子表达式一次或多次</td> </tr> <tr> <td>?</td> <td>匹配前面的子表达式零次或一次</td> </tr> <tr> <td>{n}</td> <td>匹配确定的n次</td> </tr> <tr> <td>{n,}</td> <td>至少匹配n次</td> </tr> <tr> <td>{n,m}</td> <td>最少些配n次且最多匹配m次</td> </tr> </table><h2 id="方法"><a href="#方法" class="headerlink" title="方法"></a>方法</h2><h3 id="检测一个字符串是否与正则相匹配"><a href="#检测一个字符串是否与正则相匹配" class="headerlink" title="检测一个字符串是否与正则相匹配"></a>检测一个字符串是否与正则相匹配</h3><pre class="language-js" data-language="js"><code class="language-js">reg<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span>string<span class="token punctuation">)</span> <span class="token comment">//返回值为布尔值 true匹配、false 不匹配</span>reg<span class="token punctuation">.</span><span class="token function">exec</span><span class="token punctuation">(</span>string<span class="token punctuation">)</span> <span class="token comment">//匹配成功返回数组,并确定其位置,否则返回null</span> <span class="token keyword">var</span> str <span class="token operator">=</span> <span class="token string">'abc'</span><span class="token punctuation">;</span><span class="token keyword">var</span> reg <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">[a]</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>reg<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//返回 true</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>reg<span class="token punctuation">.</span><span class="token function">exec</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 返回 ["a", index: 0, input: "abc", groups: undefined]</span></code></pre><p>当 <a href="https://www.runoob.com/jsref/jsref-exec-regexp.html">exec()</a> 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0>>最后的查找元素</p><h2 id="string类中可以支持正则的方法"><a href="#string类中可以支持正则的方法" class="headerlink" title="string类中可以支持正则的方法"></a>string类中可以支持正则的方法</h2> <table> <tr> <td>search</td> <td>检索与正则表达式相匹配的值 >>返回匹配字符串的下标,否则返回-1</td> </tr> <tr> <td>match</td> <td>找到一个或多个正则表达式的匹配 >>如果没有找到任何匹配的文本,返回null。否则,它将返回一个数组(依赖于是否具有全局标志g)</td> </tr> <tr> <td>replace</td> <td>替换与正则表达式匹配的子串 >>返回一个新的字符串</td> </tr> <tr> <td>split</td> <td>把字符串分割为字符串数组 >>返回一个字符串数组</td> </tr> </table><h2 id="常用正则表达式"><a href="#常用正则表达式" class="headerlink" title="常用正则表达式"></a>常用正则表达式</h2> <table> <tr> <td>匹配email地址</td> <td> <pre class="language-js" data-language="js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*</span><span class="token regex-delimiter">/</span></span></code></pre> </td> </tr> <tr> <td>匹配手机号码</td> <td> <pre class="language-js" data-language="js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^(0|86|17951)?(13[0-9]|15[012356789]|166|17[3678]|18[0-9]|14[57])[0-9]{8}$</span><span class="token regex-delimiter">/</span></span></code></pre> </td> </tr> <tr> <td>匹配身份证号</td> <td> <pre class="language-js" data-language="js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$</span><span class="token regex-delimiter">/</span></span></code></pre> </td> </tr> <tr> <td>匹配url地址</td> <td> <pre class="language-js" data-language="js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^https?:\/\/(([a-zA-Z0-9_-])+(\.)?)*(:\d+)?(\/((\.)?(\?)?=?&?[a-zA-Z0-9_-](\?)?)*)*$</span><span class="token regex-delimiter">/</span><span class="token regex-flags">i</span></span></code></pre> </td> </tr> <tr> <td>匹配邮编号</td> <td> <pre class="language-js" data-language="js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^[1-9]\d{5}(?!\d)$</span><span class="token regex-delimiter">/</span></span></code></pre> </td> </tr> <tr> <td>只能由英文和数字组成</td> <td> <pre class="language-js" data-language="js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^[a-z0-9]+$</span><span class="token regex-delimiter">/</span><span class="token regex-flags">i</span></span></code></pre> </td> </tr> <tr> <td>只能由英文、数字、下划线组成</td> <td> <pre class="language-js" data-language="js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^\w+$</span><span class="token regex-delimiter">/</span></span></code></pre> </td> </tr> <tr> <td>查找任何从小写a到小写z的字符</td> <td> <pre class="language-js" data-language="js"><code class="language-js"><span class="token punctuation">[</span>a<span class="token operator">-</span>z<span class="token punctuation">]</span></code></pre> </td> </tr> <tr> <td>查找任何从大写A到大写Z的字符</td> <td> <pre class="language-js" data-language="js"><code class="language-js"><span class="token punctuation">[</span><span class="token constant">A</span><span class="token operator">-</span><span class="token constant">Z</span><span class="token punctuation">]</span></code></pre> </td> </tr> <tr> <td>查找任何从0至9的数字</td> <td> <pre class="language-js" data-language="js"><code class="language-js"><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span></code></pre> </td> </tr> <tr> <td>查找括号内的任意一个字符</td> <td> <pre class="language-js" data-language="js"><code class="language-js"><span class="token punctuation">[</span>abc<span class="token punctuation">]</span></code></pre> </td> </tr> <tr> <td>查找除了括号内的任意字符</td> <td> <pre class="language-js" data-language="js"><code class="language-js"><span class="token punctuation">[</span><span class="token operator">^</span>abc<span class="token punctuation">]</span></code></pre> </td> </tr> <tr> <td>常用汉字编码范围;Unicode编码16进制的utf-8汉字编码:<font color='#BFDC86'>u4e00</font>最小中文字符 <font color='#BFDC86'>u9fa5</font>最大中文字符</td> <td> <pre class="language-js" data-language="js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^[\u4e00-\u9fa5]+$</span><span class="token regex-delimiter">/</span></span></code></pre> </td> </tr> </table>]]></content>
<categories>
<category> JS </category>
</categories>
<tags>
<tag> 正则 </tag>
<tag> js </tag>
</tags>
</entry>
<entry>
<title>ES6</title>
<link href="/2021/11/30/ES6/"/>
<url>/2021/11/30/ES6/</url>
<content type="html"><![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 (ES2015)年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。</p><span id="more"></span><h2 id="1-ECMAScript-和-JavaScript-的关系"><a href="#1-ECMAScript-和-JavaScript-的关系" class="headerlink" title="1.ECMAScript 和 JavaScript 的关系"></a>1.ECMAScript 和 JavaScript 的关系</h2><p>1996 年 11 月,JavaScript 的创造者 Netscape 公司,决定将 JavaScript 提交给标准化组织 ECMA,希望这种语言能够成为国际标准。次年,ECMA 发布 262 号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为 ECMAScript,这个版本就是 1.0 版。</p><p>该标准从一开始就是针对 JavaScript 语言制定的,但是之所以不叫 JavaScript,有两个原因。一是商标,Java 是 Sun 公司的商标,根据授权协议,只有 Netscape 公司可以合法地使用 JavaScript 这个名字,且 JavaScript 本身也已经被 Netscape 公司注册为商标。二是想体现这门语言的制定者是 ECMA,不是 Netscape,这样有利于保证这门语言的开放性和中立性。</p><p>因此,ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现(另外的 ECMAScript 方言还有 JScript 和 ActionScript)。日常场合,这两个词是可以互换的。</p><h2 id="2-ECMAScript-的历史"><a href="#2-ECMAScript-的历史" class="headerlink" title="2.ECMAScript 的历史"></a>2.ECMAScript 的历史</h2><ul><li>ES6 从开始制定到最后发布,整整用了 15 年</li><li>2000 年,ECMAScript 4.0 开始酝酿</li><li>2007 年 10 月,ECMAScript 4.0 版草案发布</li><li>2009 年 12 月,ECMAScript 5.0 版正式发布</li><li>2011 年 6 月,ECMAScript 5.1 版发布,并且成为 ISO 国际标准(ISO/IEC 16262:2011)。</li><li>2013 年 3 月,ECMAScript 6 草案冻结,不再添加新功能。新的功能设想将被放到 ECMAScript 7。</li><li>2013 年 12 月,ECMAScript 6 草案发布。然后是 12 个月的讨论期,听取各方反馈。</li><li>2015 年 6 月,ECMAScript 6 正式通过,成为国际标准。从 2000 年算起,这时已经过去了 15 年。</li><li>目前,各大浏览器对 ES6 的支持可以查看<a href="https://kangax.github.io/compat-table/es6/">kangax.github.io/compat-table/es6/</a>。</li></ul><h2 id="3-Babel-转码器"><a href="#3-Babel-转码器" class="headerlink" title="3.Babel 转码器"></a>3.Babel 转码器</h2><p><a href="https://babeljs.io/">Babel</a> 是一个广泛使用的 ES6 转码器,可以将 ES6 代码转为 ES5 代码,从而在老版本的浏览器执行。这意味着,你可以用 ES6 的方式编写程序,又不用担心现有环境是否支持。下面是一个例子。(知道就行,后面webpack课程会讲到)</p><pre class="language-none"><code class="language-none">// 转码前 es6 箭头函数input.map(item => item + 1);// 转码后 es5input.map(function (item) { return item + 1;});</code></pre><h1 id="let-amp-const"><a href="#let-amp-const" class="headerlink" title="let & const"></a>let & const</h1><h2 id="let-命令"><a href="#let-命令" class="headerlink" title="let 命令"></a>let 命令</h2><h3 id="基本用法"><a href="#基本用法" class="headerlink" title="基本用法"></a>基本用法</h3><p>ES6 新增了<code>let</code>命令,用来声明变量。它的用法类似于<code>var</code>,但是所声明的变量,只在<code>let</code>命令所在的代码块内有效。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token punctuation">{</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token keyword">var</span> b <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token punctuation">}</span>a <span class="token comment">// ReferenceError: a is not defined.</span>b <span class="token comment">// 1</span></code></pre><p>上面代码在代码块之中,分别用<code>let</code>和<code>var</code>声明了两个变量。然后在代码块之外调用这两个变量,结果<code>let</code>声明的变量报错,<code>var</code>声明的变量返回了正确的值。这表明,<code>let</code>声明的变量只在它所在的代码块有效。</p><p><code>for</code>循环的计数器,就很合适使用<code>let</code>命令。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> <span class="token number">10</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ...</span><span class="token punctuation">}</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// ReferenceError: i is not defined</span></code></pre><p>上面代码中,计数器<code>i</code>只在<code>for</code>循环体内有效,在循环体外引用就会报错。</p><p>下面的代码如果使用<code>var</code>,最后输出的是<code>10</code>。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">var</span> i<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span>i<span class="token operator"><</span><span class="token number">10</span><span class="token punctuation">;</span>i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//10</span><span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> <span class="token number">10</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> a<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token punctuation">}</span>a<span class="token punctuation">[</span><span class="token number">6</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span></code></pre><p>上面代码中,变量<code>i</code>是<code>var</code>命令声明的,在全局范围内都有效,所以全局只有一个变量<code>i</code>。每一次循环,变量<code>i</code>的值都会发生改变,而循环内被赋给数组<code>a</code>的函数内部的<code>console.log(i)</code>,里面的<code>i</code>指向的就是全局的<code>i</code>。也就是说,所有数组<code>a</code>的成员里面的<code>i</code>,指向的都是同一个<code>i</code>,导致运行时输出的是最后一轮的<code>i</code>的值,也就是 10。</p><p>如果使用<code>let</code>,声明的变量仅在块级作用域内有效,最后输出的是 6。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> <span class="token number">10</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> a<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token punctuation">}</span>a<span class="token punctuation">[</span><span class="token number">6</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 6</span></code></pre><p>上面代码中,变量<code>i</code>是<code>let</code>声明的,当前的<code>i</code>只在本轮循环有效,所以每一次循环的<code>i</code>其实都是一个新的变量,所以最后输出的是<code>6</code>。你可能会问,如果每一轮循环的变量<code>i</code>都是重新声明的,那它怎么知道上一轮循环的值,从而计算出本轮循环的值?这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量<code>i</code>时,就在上一轮循环的基础上进行计算。</p><p>另外,<code>for</code>循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。(作用域相互独立)</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> <span class="token number">3</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token string">'abc'</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">// abc</span><span class="token comment">// abc</span><span class="token comment">// abc</span></code></pre><p>上面代码正确运行,输出了 3 次<code>abc</code>。这表明函数内部的变量<code>i</code>与循环变量<code>i</code>不在同一个作用域,有各自单独的作用域。</p><h3 id="不存在变量提升"><a href="#不存在变量提升" class="headerlink" title="不存在变量提升"></a>不存在变量提升</h3><p><code>var</code>命令会发生“变量提升”现象,即变量可以在声明之前使用,值为<code>undefined</code>。这种现象多多少少是有些奇怪的,按照一般的逻辑,变量应该在声明语句之后才可以使用。</p><p>为了纠正这种现象,<code>let</code>命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// var 的情况</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>foo<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 输出undefined</span><span class="token keyword">var</span> foo <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span><span class="token comment">// let 的情况</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>bar<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 报错ReferenceError</span><span class="token keyword">let</span> bar <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span></code></pre><p>上面代码中,变量<code>foo</code>用<code>var</code>命令声明,会发生变量提升,即脚本开始运行时,变量<code>foo</code>已经存在了,但是没有值,所以会输出<code>undefined</code>。变量<code>bar</code>用<code>let</code>命令声明,不会发生变量提升。这表示在声明它之前,变量<code>bar</code>是不存在的,这时如果用到它,就会抛出一个错误。</p><h3 id="暂时性死区"><a href="#暂时性死区" class="headerlink" title="暂时性死区"></a>暂时性死区</h3><p>只要块级作用域内存在<code>let</code>命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> tmp <span class="token operator">=</span> <span class="token number">123</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> tmp <span class="token operator">=</span> <span class="token string">'abc'</span><span class="token punctuation">;</span> <span class="token comment">// ReferenceError</span> <span class="token keyword">let</span> tmp<span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><p>上面代码中,存在全局变量<code>tmp</code>,但是块级作用域内<code>let</code>又声明了一个局部变量<code>tmp</code>,导致后者绑定这个块级作用域,所以在<code>let</code>声明变量前,对<code>tmp</code>赋值会报错。</p><p>ES6 明确规定,如果区块中存在<code>let</code>和<code>const</code>命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。</p><p>总之,在代码块内,使用<code>let</code>命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// TDZ开始</span> tmp <span class="token operator">=</span> <span class="token string">'abc'</span><span class="token punctuation">;</span> <span class="token comment">// ReferenceError</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>tmp<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ReferenceError</span> <span class="token keyword">let</span> tmp<span class="token punctuation">;</span> <span class="token comment">// TDZ结束</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>tmp<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span> tmp <span class="token operator">=</span> <span class="token number">123</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>tmp<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 123</span><span class="token punctuation">}</span></code></pre><p>上面代码中,在<code>let</code>命令声明变量<code>tmp</code>之前,都属于变量<code>tmp</code>的“死区”。</p><p>“暂时性死区”也意味着<code>typeof</code>不再是一个百分之百安全的操作。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">typeof</span> x<span class="token punctuation">;</span> <span class="token comment">// ReferenceError</span><span class="token keyword">let</span> x<span class="token punctuation">;</span></code></pre><p>上面代码中,变量<code>x</code>使用<code>let</code>命令声明,所以在声明之前,都属于<code>x</code>的“死区”,只要用到该变量就会报错。因此,<code>typeof</code>运行时就会抛出一个<code>ReferenceError</code>。</p><p>作为比较,如果一个变量根本没有被声明,使用<code>typeof</code>反而不会报错。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> a<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// "undefined"</span><span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> </code></pre><p>上面代码中,typeof a 结果返回“undefined”。所以,在没有<code>let</code>之前,<code>typeof</code>运算符是百分之百安全的,永远不会报错。现在这一点不成立了。这样的设计是为了让大家养成良好的编程习惯,变量一定要在声明之后使用,否则就报错。</p><p>有些“死区”比较隐蔽,不太容易发现。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">bar</span><span class="token punctuation">(</span><span class="token parameter">x <span class="token operator">=</span> y<span class="token punctuation">,</span> y <span class="token operator">=</span> <span class="token number">2</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">[</span>x<span class="token punctuation">,</span> y<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">bar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 报错</span></code></pre><p>上面代码中,调用<code>bar</code>函数之所以报错(某些实现可能不报错),是因为参数<code>x</code>默认值等于另一个参数<code>y</code>,而此时<code>y</code>还没有声明,属于“死区”。如果<code>y</code>的默认值是<code>x</code>,就不会报错,因为此时<code>x</code>已经声明了。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">bar</span><span class="token punctuation">(</span><span class="token parameter">x <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">,</span> y <span class="token operator">=</span> x</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">[</span>x<span class="token punctuation">,</span> y<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">bar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [2, 2]</span></code></pre><p>另外,下面的代码也会报错,与<code>var</code>的行为不同。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 不报错</span><span class="token keyword">var</span> x <span class="token operator">=</span> x<span class="token punctuation">;</span><span class="token comment">// 报错</span><span class="token keyword">let</span> x <span class="token operator">=</span> x<span class="token punctuation">;</span><span class="token comment">// ReferenceError: x is not defined</span></code></pre><p>上面代码报错,也是因为暂时性死区。使用<code>let</code>声明变量时,只要变量在还没有声明完成前使用,就会报错。上面这行就属于这个情况,在变量<code>x</code>的声明语句还没有执行完成前,就去取<code>x</code>的值,导致报错”x 未定义“。</p><p>ES6 规定暂时性死区和<code>let</code>、<code>const</code>语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。这样的错误在 ES5 是很常见的,现在有了这种规定,避免此类错误就很容易了。</p><p>总之,暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。</p><h3 id="不允许重复声明"><a href="#不允许重复声明" class="headerlink" title="不允许重复声明"></a>不允许重复声明</h3><p><code>let</code>不允许在相同作用域内,重复声明同一个变量。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 报错</span><span class="token keyword">function</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">// 报错</span><span class="token keyword">function</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><p>因此,不能在函数内部重新声明参数。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token parameter">arg</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> arg<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// 报错</span><span class="token keyword">function</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token parameter">arg</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> arg<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// 不报错</span></code></pre><h2 id="块级作用域"><a href="#块级作用域" class="headerlink" title="块级作用域"></a>块级作用域</h2><h3 id="为什么需要块级作用域?"><a href="#为什么需要块级作用域?" class="headerlink" title="为什么需要块级作用域?"></a>为什么需要块级作用域?</h3><p>ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。</p><p>第一种场景,内层变量可能会覆盖外层变量。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> tmp <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>tmp<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> tmp <span class="token operator">=</span> <span class="token string">'hello world'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre><p>上面代码的原意是,<code>if</code>代码块的外部使用外层的<code>tmp</code>变量,内部使用内层的<code>tmp</code>变量。但是,函数<code>f</code>执行后,输出结果为<code>undefined</code>,原因在于变量提升,导致内层的<code>tmp</code>变量覆盖了外层的<code>tmp</code>变量。</p><p>第二种场景,用来计数的循环变量泄露为全局变量。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> s <span class="token operator">=</span> <span class="token string">'hello'</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> s<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>s<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 5</span></code></pre><p>上面代码中,变量<code>i</code>只用来控制循环,但是循环结束后,它并没有消失,泄露成了全局变量。</p><h3 id="ES6-的块级作用域"><a href="#ES6-的块级作用域" class="headerlink" title="ES6 的块级作用域"></a>ES6 的块级作用域</h3><p><code>let</code>实际上为 JavaScript 新增了块级作用域。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">f1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> n <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> n <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 5</span><span class="token punctuation">}</span></code></pre><p>上面的函数有两个代码块,都声明了变量<code>n</code>,运行后输出 5。这表示外层代码块不受内层代码块的影响。如果两次都使用<code>var</code>定义变量<code>n</code>,最后输出的值才是 10。</p><p>ES6 允许块级作用域的任意嵌套。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token punctuation">{</span><span class="token keyword">let</span> insane <span class="token operator">=</span> <span class="token string">'Hello World'</span><span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>insane<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 报错</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre><p>上面代码使用了一个五层的块级作用域,每一层都是一个单独的作用域。第四层作用域无法读取第五层作用域的内部变量。</p><p>内层作用域可以定义外层作用域的同名变量。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token keyword">let</span> insane <span class="token operator">=</span> <span class="token string">'Hello World'</span><span class="token punctuation">;</span> <span class="token punctuation">{</span><span class="token keyword">let</span> insane <span class="token operator">=</span> <span class="token string">'Hello World'</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre><p>块级作用域的出现,实际上使得获得广泛应用的匿名立即执行函数表达式(匿名 IIFE)不再必要了。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// IIFE 写法</span><span class="token punctuation">;</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> tmp <span class="token operator">=</span> <span class="token operator">...</span><span class="token punctuation">;</span> <span class="token operator">...</span><span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token constant">IIFE</span>的好处:<span class="token number">1.</span>避免作用域命名污染<span class="token number">2.</span>提升性能(减少了对作用域的查找)<span class="token number">3.</span>避免全局命名冲突<span class="token number">4.</span>保存闭包状态<span class="token comment">// 块级作用域写法</span><span class="token punctuation">{</span> <span class="token keyword">let</span> tmp <span class="token operator">=</span> <span class="token operator">...</span><span class="token punctuation">;</span> <span class="token operator">...</span><span class="token punctuation">}</span></code></pre><h3 id="块级作用域与函数声明"><a href="#块级作用域与函数声明" class="headerlink" title="块级作用域与函数声明"></a>块级作用域与函数声明</h3><p>函数能不能在块级作用域之中声明?这是一个相当令人混淆的问题。</p><p>ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 情况一</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment">// 情况二</span><span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token keyword">catch</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ...</span><span class="token punctuation">}</span></code></pre><p>上面两种函数声明,根据 ES5 的规定都是非法的。</p><p>但是,浏览器没有遵守这个规定,为了兼容以前的旧代码,还是支持在块级作用域之中声明函数,因此上面两种情况实际都能运行,不会报错。</p><p>ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。ES6 规定,块级作用域之中,函数声明语句的行为类似于<code>let</code>,在块级作用域之外不可引用。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'I am outside!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 重复声明一次函数f</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'I am inside!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>上面代码在 ES5 中运行,会得到“I am inside!”,因为在<code>if</code>内声明的函数<code>f</code>会被提升到函数头部,实际运行的代码如下。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// ES5 环境</span><span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'I am outside!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'I am inside!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>ES6 就完全不一样了,理论上会得到“I am outside!”。因为块级作用域内声明的函数类似于<code>let</code>,对作用域之外没有影响。但是,如果你真的在 ES6 浏览器中运行一下上面的代码,是会报错的,这是为什么呢?</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 浏览器的 ES6 环境</span><span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'I am outside!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 重复声明一次函数f</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'I am inside!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// Uncaught TypeError: f is not a function</span></code></pre><p>上面的代码在 ES6 浏览器中,都会报错。</p><p>原来,如果改变了块级作用域内声明的函数的处理规则,显然会对老代码产生很大影响。为了减轻因此产生的不兼容问题,ES6 在<a href="http://www.ecma-international.org/ecma-262/6.0/index.html#sec-block-level-function-declarations-web-legacy-compatibility-semantics">附录 B</a>里面规定,浏览器的实现可以不遵守上面的规定,有自己的<a href="http://stackoverflow.com/questions/31419897/what-are-the-precise-semantics-of-block-level-functions-in-es6">行为方式</a>。</p><ul><li>允许在块级作用域内声明函数。</li><li>函数声明类似于<code>var</code>,即会提升到全局作用域或函数作用域的头部。</li><li>同时,函数声明还会提升到所在的块级作用域的头部。</li></ul><p>注意,上面三条规则只对 ES6 的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作<code>let</code>处理。</p><p>根据这三条规则,浏览器的 ES6 环境中,块级作用域内声明的函数,行为类似于<code>var</code>声明的变量。上面的例子实际运行的代码如下。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 浏览器的 ES6 环境</span><span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'I am outside!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> f <span class="token operator">=</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'I am inside!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// Uncaught TypeError: f is not a function</span></code></pre><p>考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 块级作用域内部的函数声明语句,建议不要使用</span><span class="token punctuation">{</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token string">'secret'</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment">// 块级作用域内部,优先使用函数表达式</span><span class="token punctuation">{</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token string">'secret'</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token function-variable function">f</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><p>另外,还有一个需要注意的地方。ES6 的块级作用域必须有大括号,如果没有大括号,JavaScript 引擎就认为不存在块级作用域。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 第一种写法,报错</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token comment">// 第二种写法,不报错</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><p>上面代码中,第一种写法没有大括号,所以不存在块级作用域,而<code>let</code>只能出现在当前作用域的顶层,所以报错。第二种写法有大括号,所以块级作用域成立。</p><h2 id="const-命令"><a href="#const-命令" class="headerlink" title="const 命令"></a>const 命令</h2><h3 id="基本用法-1"><a href="#基本用法-1" class="headerlink" title="基本用法"></a>基本用法</h3><p><code>const</code>声明一个只读的常量。一旦声明,常量的值就不能改变。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token constant">PI</span> <span class="token operator">=</span> <span class="token number">3.1415</span><span class="token punctuation">;</span><span class="token constant">PI</span> <span class="token comment">// 3.1415</span><span class="token constant">PI</span> <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span><span class="token comment">// TypeError: Assignment to constant variable.</span></code></pre><p>上面代码表明改变常量的值会报错。</p><p><code>const</code>声明的变量不得改变值,这意味着,<code>const</code>一旦声明变量,就必须立即初始化,不能留到以后赋值。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> foo<span class="token punctuation">;</span><span class="token comment">// SyntaxError: Missing initializer in const declaration</span></code></pre><p>上面代码表示,对于<code>const</code>来说,只声明不赋值,就会报错。</p><p><code>const</code>的作用域与<code>let</code>命令相同:只在声明所在的块级作用域内有效。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token constant">MAX</span> <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token constant">MAX</span> <span class="token comment">// Uncaught ReferenceError: MAX is not defined</span></code></pre><p><code>const</code>命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">MAX</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ReferenceError</span> <span class="token keyword">const</span> <span class="token constant">MAX</span> <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><p>上面代码在常量<code>MAX</code>声明之前就调用,结果报错。</p><p><code>const</code>声明的常量,也与<code>let</code>一样不可重复声明。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> message <span class="token operator">=</span> <span class="token string">"Hello!"</span><span class="token punctuation">;</span><span class="token keyword">let</span> age <span class="token operator">=</span> <span class="token number">25</span><span class="token punctuation">;</span><span class="token comment">// 以下两行都会报错</span><span class="token keyword">const</span> message <span class="token operator">=</span> <span class="token string">"Goodbye!"</span><span class="token punctuation">;</span><span class="token keyword">const</span> age <span class="token operator">=</span> <span class="token number">30</span><span class="token punctuation">;</span></code></pre><h3 id="本质"><a href="#本质" class="headerlink" title="本质"></a>本质</h3><p><code>const</code>实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,<code>const</code>只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> foo <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">// 为 foo 添加一个属性,可以成功</span>foo<span class="token punctuation">.</span>prop <span class="token operator">=</span> <span class="token number">123</span><span class="token punctuation">;</span>foo<span class="token punctuation">.</span>prop <span class="token comment">// 123</span><span class="token comment">// 将 foo 指向另一个对象,就会报错</span>foo <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// TypeError: "foo" is read-only</span></code></pre><p>上面代码中,常量<code>foo</code>储存的是一个地址,这个地址指向一个对象。不可变的只是这个地址,即不能把<code>foo</code>指向另一个地址,但对象本身是可变的,所以依然可以为其添加新属性。</p><p>下面是另一个例子。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>a<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">'Hello'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 可执行</span>a<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// 可执行</span>a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'Dave'</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// 报错</span></code></pre><p>上面代码中,常量<code>a</code>是一个数组,这个数组本身是可写的,但是如果将另一个数组赋值给<code>a</code>,就会报错。</p><p>如果真的想将对象冻结,应该使用<code>Object.freeze</code>方法。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> foo <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">freeze</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 常规模式时,下面一行不起作用;</span><span class="token comment">// 严格模式时,该行会报错</span>foo<span class="token punctuation">.</span>prop <span class="token operator">=</span> <span class="token number">123</span><span class="token punctuation">;</span></code></pre><p>上面代码中,常量<code>foo</code>指向一个冻结的对象,所以添加新属性不起作用,<a href="https://www.runoob.com/js/js-strict.html">严格模式</a>时还会报错。</p><p>除了将对象本身冻结,对象的属性也应该冻结。下面是一个将对象彻底冻结的函数。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> <span class="token function-variable function">constantize</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> Object<span class="token punctuation">.</span><span class="token function">freeze</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token parameter">key<span class="token punctuation">,</span> i</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token keyword">typeof</span> obj<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">===</span> <span class="token string">'object'</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">constantize</span><span class="token punctuation">(</span> obj<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre><h3 id="ES6-声明变量的六种方法"><a href="#ES6-声明变量的六种方法" class="headerlink" title="ES6 声明变量的六种方法"></a>ES6 声明变量的六种方法</h3><p>ES5 只有两种声明变量的方法:<code>var</code>命令和<code>function</code>命令。ES6 除了添加<code>let</code>和<code>const</code>命令,后面章节还会提到,另外两种声明变量的方法:<code>import</code>命令和<code>class</code>命令。所以,ES6 一共有 6 种声明变量的方法。</p><h2 id="顶层对象的属性"><a href="#顶层对象的属性" class="headerlink" title="顶层对象的属性"></a>顶层对象的属性</h2><p>顶层对象,在浏览器环境指的是<code>window</code>对象,在 Node 指的是<code>global</code>对象。ES5 之中,顶层对象的属性与全局变量是等价的。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript">window<span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>a <span class="token comment">// 1</span>a <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>window<span class="token punctuation">.</span>a <span class="token comment">// 2</span></code></pre><p>上面代码中,顶层对象的属性赋值与全局变量的赋值,是同一件事。</p><p>顶层对象的属性与全局变量挂钩,被认为是 JavaScript 语言最大的设计败笔之一。这样的设计带来了几个很大的问题,首先是没法在编译时就报出变量未声明的错误,只有运行时才能知道(因为全局变量可能是顶层对象的属性创造的,而属性的创造是动态的);其次,程序员很容易不知不觉地就创建了全局变量(比如打字出错);最后,顶层对象的属性是到处可以读写的,这非常不利于模块化编程。另一方面,<code>window</code>对象有实体含义,指的是浏览器的窗口对象,顶层对象是一个有实体含义的对象,也是不合适的。</p><p>ES6 为了改变这一点,一方面规定,为了保持兼容性,<code>var</code>命令和<code>function</code>命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,<code>let</code>命令、<code>const</code>命令、<code>class</code>命令声明的全局变量,不属于顶层对象的属性。也就是说,从 ES6 开始,全局变量将逐步与顶层对象的属性脱钩。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token comment">// 如果在 Node 的 REPL 环境,可以写成 global.a</span><span class="token comment">// 或者采用通用方法,写成 this.a</span>window<span class="token punctuation">.</span>a <span class="token comment">// 1</span><span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>window<span class="token punctuation">.</span>b <span class="token comment">// undefined</span></code></pre><p>上面代码中,全局变量<code>a</code>由<code>var</code>命令声明,所以它是顶层对象的属性;全局变量<code>b</code>由<code>let</code>命令声明,所以它不是顶层对象的属性,返回<code>undefined</code>。</p><h2 id="globalThis-对象"><a href="#globalThis-对象" class="headerlink" title="globalThis 对象"></a>globalThis 对象</h2><p>JavaScript 语言存在一个顶层对象,它提供全局环境(即全局作用域),所有代码都是在这个环境中运行。但是,顶层对象在各种实现里面是不统一的。</p><ul><li>浏览器里面,顶层对象是<code>window</code>,但 Node 和 Web Worker 没有<code>window</code>。</li><li>浏览器和 Web Worker 里面,<code>self</code>也指向顶层对象,但是 Node 没有<code>self</code>。</li><li>Node 里面,顶层对象是<code>global</code>,但其他环境都不支持。</li></ul><p>同一段代码为了能够在各种环境,都能取到顶层对象,现在一般是使用<code>this</code>变量,但是有局限性。</p><ul><li>全局环境中,<code>this</code>会返回顶层对象。但是,Node.js 模块中<code>this</code>返回的是当前模块,ES6 模块中<code>this</code>返回的是<code>undefined</code>。</li><li>函数里面的<code>this</code>,如果函数不是作为对象的方法运行,而是单纯作为函数运行,<code>this</code>会指向顶层对象。但是,严格模式下,这时<code>this</code>会返回<code>undefined</code>。</li><li>不管是严格模式,还是普通模式,<code>new Function('return this')()</code>,总是会返回全局对象。但是,如果浏览器用了 CSP(Content Security Policy,内容安全策略),那么<code>eval</code>、<code>new Function</code>这些方法都可能无法使用。</li></ul><p>综上所述,很难找到一种方法,可以在所有情况下,都取到顶层对象。</p><p><a href="https://github.com/tc39/proposal-global">ES2020</a> 在语言标准的层面,引入<code>globalThis</code>作为顶层对象。也就是说,任何环境下,<code>globalThis</code>都是存在的,都可以从它拿到顶层对象,指向全局环境下的<code>this</code>。</p><pre class="language-none"><code class="language-none">demo.js浏览器环境:console.log(globalThis); //windownode环境console.log(globalThis); //global</code></pre><h1 id="变量的解构赋值"><a href="#变量的解构赋值" class="headerlink" title="变量的解构赋值"></a>变量的解构赋值</h1><h2 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h2><p>解构赋值是对赋值运算符的扩展。他是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。在代码书写上简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。</p><ol><li>数组的解构赋值</li><li>对象的解构赋值</li><li>字符串的解构赋值</li><li>数值和布尔值的解构赋值</li><li>函数参数的解构赋值</li><li>圆括号问题</li><li>用途</li></ol><h2 id="数组的解构赋值"><a href="#数组的解构赋值" class="headerlink" title="数组的解构赋值"></a>数组的解构赋值</h2><h3 id="基本用法-2"><a href="#基本用法-2" class="headerlink" title="基本用法"></a>基本用法</h3><p>ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。以前,为变量赋值,只能直接指定值。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span><span class="token keyword">let</span> c <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span></code></pre><p>ES6 允许写成下面这样。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> <span class="token punctuation">[</span>a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> c<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span>数组解构赋值:就是等号左右两边按照位置对应关系,从数组中提取值,对变量进行赋值的操作。本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。</code></pre><p>案例分析:</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">[</span>foo<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">[</span>bar<span class="token punctuation">]</span><span class="token punctuation">,</span> baz<span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span>foo <span class="token comment">// 1</span>bar <span class="token comment">// 2</span>baz <span class="token comment">// 3</span><span class="token keyword">let</span> <span class="token punctuation">[</span> <span class="token punctuation">,</span> <span class="token punctuation">,</span> third<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"foo"</span><span class="token punctuation">,</span> <span class="token string">"bar"</span><span class="token punctuation">,</span> <span class="token string">"baz"</span><span class="token punctuation">]</span><span class="token punctuation">;</span>third <span class="token comment">// "baz"</span><span class="token keyword">let</span> <span class="token punctuation">[</span>x<span class="token punctuation">,</span> <span class="token punctuation">,</span> y<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span>x <span class="token comment">// 1</span>y <span class="token comment">// 3</span></code></pre><p>如果解构不成功,变量的值就等于<code>undefined</code>。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">[</span>foo<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">let</span> <span class="token punctuation">[</span>bar<span class="token punctuation">,</span> foo<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre><p>不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">[</span>x<span class="token punctuation">,</span> y<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span>x <span class="token comment">// 1</span>y <span class="token comment">// 2</span><span class="token keyword">let</span> <span class="token punctuation">[</span>a<span class="token punctuation">,</span> <span class="token punctuation">[</span>b<span class="token punctuation">]</span><span class="token punctuation">,</span> d<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">;</span>a <span class="token comment">// 1</span>b <span class="token comment">// 2</span>d <span class="token comment">// 4</span></code></pre><p>如果等号的右边不是数组(或者严格地说,不是可遍历的结构,参见《Iterator》一章),那么将会报错。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">// 报错</span><span class="token keyword">let</span> <span class="token punctuation">[</span>foo<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">let</span> <span class="token punctuation">[</span>foo<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span><span class="token keyword">let</span> <span class="token punctuation">[</span>foo<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">NaN</span><span class="token punctuation">;</span><span class="token keyword">let</span> <span class="token punctuation">[</span>foo<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span><span class="token keyword">let</span> <span class="token punctuation">[</span>foo<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><span class="token keyword">let</span> <span class="token punctuation">[</span>foo<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>Iterator接口:是一个遍历器对象,为各种不同的数据结构提供统一的访问机制原生具备 Iterator 接口的数据结构如下。ArrayMapSetStringTypedArray函数的 arguments 对象NodeList 对象</code></pre><h3 id="默认值"><a href="#默认值" class="headerlink" title="默认值"></a>默认值</h3><ul><li><p>解构赋值允许指定默认值。</p></li><li><p>```js<br>let [foo = true] = [];<br>foo // true</p><p>let [x, y = ‘b’] = [‘a’]; // x=’a’, y=’b’<br>let [x, y = ‘b’] = [‘a’, undefined]; // x=’a’, y=’b’</p><pre class="language-none"><code class="language-none">- 注意,ES6 内部使用严格相等运算符(`===`),判断一个位置是否有值。所以,只有当一个数组成员严格等于`undefined`,默认值才会生效。- ```js let [x = 1] = [undefined]; x // 1 let [x = 1] = [null]; x // null</code></pre></li><li><p>如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。</p></li><li><p>```js<br>function f() {<br> console.log(‘aaa’);<br>}</p><p>let [x = f()] = [1];</p><pre class="language-none"><code class="language-none">### 三点运算符```js符号:...根据用法:又可称之为1.展开运算符//把a数组中的数据,展开,放入到arr中,就可以使用 ... 运算符let a = [1,2,3,4,5,6];let arr = ['aa','bb','cc',...a]arr //['aa','bb','cc',1,2,3,4,5,6]2.剩余运算符//按照数组位置对应关系,进行赋值,把剩余的数据,打包以数组形式,赋值给dlet [a,b,c,...d] = [1,2,3,4,5,6,7,8,9,10];a //1b //2c //3d //[4,5,6,7,8,9,10]</code></pre></li></ul><h2 id="对象的解构赋值"><a href="#对象的解构赋值" class="headerlink" title="对象的解构赋值"></a>对象的解构赋值</h2><h3 id="基本用法-3"><a href="#基本用法-3" class="headerlink" title="基本用法"></a>基本用法</h3><p>解构不仅可以用于数组,还可以用于对象。对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。</p><p>数组的解构是按照位置对应关系赋值,对象的解构赋值是按照键值对的对应关系进行赋值</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">{</span>name<span class="token operator">:</span>myname<span class="token punctuation">,</span>age<span class="token operator">:</span>myage<span class="token punctuation">,</span>sex<span class="token operator">:</span>mysex<span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token string">'lisi'</span><span class="token punctuation">,</span>age<span class="token operator">:</span><span class="token number">25</span><span class="token punctuation">}</span>myname <span class="token comment">//lisi</span>myage <span class="token comment">//25</span>mysex <span class="token comment">//undefined</span></code></pre><p>对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">{</span>log<span class="token operator">:</span>log<span class="token punctuation">,</span>dir<span class="token operator">:</span>dir<span class="token punctuation">}</span> <span class="token operator">=</span> console<span class="token punctuation">;</span><span class="token comment">//把console对象的方法log(控制台输出信息) /dir(展示一个对象下的所有的属性和方法) 通过解构赋值给 log 和dir变量</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'xxx'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> 等价于 <span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'xxx'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">dir</span><span class="token punctuation">(</span>window<span class="token punctuation">)</span><span class="token punctuation">;</span> 等价于 <span class="token function">dir</span><span class="token punctuation">(</span>window<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> <span class="token operator">?</span> <span class="token operator">=</span> Math<span class="token punctuation">;</span> <span class="token operator">?</span>部分怎么写 </code></pre><p>对象的解构赋值可以是下面形式的简写(参见<a href="https://es6.ruanyifeng.com/#docs/object">《对象的扩展》</a>一章)</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">{</span> foo<span class="token operator">:</span> foo<span class="token punctuation">,</span> bar<span class="token operator">:</span> bar <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span> foo<span class="token operator">:</span> <span class="token string">'aaa'</span><span class="token punctuation">,</span> bar<span class="token operator">:</span> <span class="token string">'bbb'</span> <span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token keyword">let</span> <span class="token punctuation">{</span> foo<span class="token punctuation">,</span> bar <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span> foo<span class="token operator">:</span> <span class="token string">'aaa'</span><span class="token punctuation">,</span> bar<span class="token operator">:</span> <span class="token string">'bbb'</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre><p>与数组一样,解构也可以用于嵌套结构的对象</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> list<span class="token operator">:</span><span class="token punctuation">[</span><span class="token string">'aa'</span><span class="token punctuation">,</span><span class="token string">'bb'</span><span class="token punctuation">,</span><span class="token string">'cc'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> hobby<span class="token operator">:</span><span class="token punctuation">{</span> ball<span class="token operator">:</span><span class="token punctuation">[</span><span class="token string">'篮球'</span><span class="token punctuation">,</span><span class="token string">'足球'</span><span class="token punctuation">,</span><span class="token string">'乒乓球'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> fruits<span class="token operator">:</span><span class="token punctuation">[</span><span class="token string">'榴莲'</span><span class="token punctuation">,</span><span class="token string">'百香果'</span><span class="token punctuation">,</span><span class="token string">'杨桃'</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token keyword">let</span> <span class="token punctuation">{</span>list<span class="token punctuation">,</span>hobby<span class="token punctuation">,</span>list<span class="token operator">:</span><span class="token punctuation">[</span>a<span class="token punctuation">,</span>b<span class="token punctuation">,</span>c<span class="token punctuation">]</span><span class="token punctuation">}</span> <span class="token operator">=</span> objlist <span class="token comment">//['aa','bb','cc']</span>hobby <span class="token comment">//{ball:['篮球','足球','乒乓球'],fruits:['榴莲','百香果','杨桃']}</span>a <span class="token comment">//aa</span>b <span class="token comment">//bb</span>c <span class="token comment">// cc</span></code></pre><h3 id="默认值-1"><a href="#默认值-1" class="headerlink" title="默认值"></a>默认值</h3><p>对象的解构也可以指定默认值,默认值生效的条件是,对象的属性值严格等于<code>undefined</code>。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">{</span>x<span class="token punctuation">,</span>y<span class="token operator">=</span><span class="token number">20</span><span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span>x<span class="token operator">:</span><span class="token number">10</span><span class="token punctuation">}</span>x<span class="token comment">//10</span>y<span class="token comment">//20</span><span class="token keyword">var</span> <span class="token punctuation">{</span>x <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>x <span class="token comment">// 3</span><span class="token keyword">var</span> <span class="token punctuation">{</span>x<span class="token punctuation">,</span> y <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span>x<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">;</span>x <span class="token comment">// 1</span>y <span class="token comment">// 5</span><span class="token keyword">var</span> <span class="token punctuation">{</span>x <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span>x<span class="token operator">:</span> <span class="token keyword">undefined</span><span class="token punctuation">}</span><span class="token punctuation">;</span>x <span class="token comment">// 3</span><span class="token keyword">var</span> <span class="token punctuation">{</span>x <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span>x<span class="token operator">:</span> <span class="token keyword">null</span><span class="token punctuation">}</span><span class="token punctuation">;</span>x <span class="token comment">// null</span></code></pre><h3 id="注意点"><a href="#注意点" class="headerlink" title="注意点"></a>注意点</h3><p>(1)如果要将一个已经声明的变量用于解构赋值,必须非常小心。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 错误的写法</span><span class="token keyword">let</span> x<span class="token punctuation">;</span><span class="token punctuation">{</span>x<span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span>x<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">// SyntaxError: syntax error</span><span class="token comment">//right</span><span class="token keyword">let</span> <span class="token punctuation">{</span>x<span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span>x<span class="token operator">:</span><span class="token number">1</span><span class="token punctuation">}</span></code></pre><p>上面代码的写法会报错,因为 JavaScript 引擎会将<code>{x}</code>理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 正确的写法</span><span class="token keyword">let</span> x<span class="token punctuation">;</span><span class="token punctuation">(</span><span class="token punctuation">{</span>x<span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span>x<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> x<span class="token punctuation">;</span><span class="token operator">...</span><span class="token punctuation">.</span><span class="token operator">...</span><span class="token punctuation">.</span><span class="token operator">...</span><span class="token punctuation">.</span><span class="token punctuation">(</span><span class="token punctuation">{</span>x<span class="token punctuation">}</span> <span class="token operator">=</span> obj<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>上面代码将整个解构赋值语句,放在一个圆括号里面,就可以正确执行。关于圆括号与解构赋值的关系,参见下文。</p><p>(2)解构赋值允许等号左边的模式之中,不放置任何变量名。因此,可以写出非常古怪的赋值表达式。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token string">'abc'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>上面的表达式虽然毫无意义,但是语法是合法的,可以执行。</p><p>(3)由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span> 等价于 <span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token number">0</span><span class="token operator">:</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token operator">:</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token operator">:</span><span class="token number">3</span><span class="token punctuation">}</span><span class="token keyword">let</span> <span class="token punctuation">{</span><span class="token number">0</span> <span class="token operator">:</span> first<span class="token punctuation">,</span> <span class="token punctuation">[</span>arr<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">:</span> last<span class="token punctuation">}</span> <span class="token operator">=</span> arr<span class="token punctuation">;</span>first <span class="token comment">// 1</span>last <span class="token comment">// 3</span></code></pre><p>上面代码对数组进行对象解构。数组<code>arr</code>的<code>0</code>键对应的值是<code>1</code>,<code>[arr.length - 1]</code>就是<code>2</code>键,对应的值是<code>3</code>。方括号这种写法,属于“属性名表达式”(参见《对象的扩展》一章)。</p><h2 id="字符串的解构赋值"><a href="#字符串的解构赋值" class="headerlink" title="字符串的解构赋值"></a>字符串的解构赋值</h2><p>字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token punctuation">[</span>a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> c<span class="token punctuation">,</span> d<span class="token punctuation">,</span> e<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'hello'</span><span class="token punctuation">;</span> <span class="token string">'hello'</span> <span class="token operator">==</span> <span class="token punctuation">[</span><span class="token string">'h'</span><span class="token punctuation">,</span><span class="token string">'e'</span><span class="token punctuation">,</span><span class="token string">'l'</span><span class="token punctuation">,</span><span class="token string">'l'</span><span class="token punctuation">,</span><span class="token string">'0'</span><span class="token punctuation">]</span>a <span class="token comment">// "h"</span>b <span class="token comment">// "e"</span>c <span class="token comment">// "l"</span>d <span class="token comment">// "l"</span>e <span class="token comment">// "o"</span></code></pre><p>类似数组的对象都有一个<code>length</code>属性,因此还可以对这个属性解构赋值。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> <span class="token punctuation">{</span>length <span class="token operator">:</span> len<span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token string">'hello'</span><span class="token punctuation">;</span>len <span class="token comment">// 5</span><span class="token comment">//解析 'hello'</span><span class="token keyword">let</span> hello <span class="token operator">=</span> <span class="token punctuation">{</span> length<span class="token operator">:</span><span class="token number">5</span><span class="token punctuation">}</span><span class="token keyword">let</span> <span class="token punctuation">{</span>length<span class="token operator">:</span>len<span class="token punctuation">}</span> <span class="token operator">=</span> hello<span class="token punctuation">;</span></code></pre><h2 id="数值和布尔值的解构赋值"><a href="#数值和布尔值的解构赋值" class="headerlink" title="数值和布尔值的解构赋值"></a>数值和布尔值的解构赋值</h2><p>解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> <span class="token punctuation">{</span>toString<span class="token operator">:</span> s<span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token number">123</span><span class="token punctuation">;</span>s <span class="token operator">===</span> <span class="token class-name">Number</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>toString <span class="token comment">// true</span><span class="token keyword">let</span> <span class="token punctuation">{</span>toString<span class="token operator">:</span> s<span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>s <span class="token operator">===</span> <span class="token class-name">Boolean</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>toString <span class="token comment">// true</span></code></pre><p>上面代码中,数值和布尔值的包装对象都有<code>toString</code>属性,因此变量<code>s</code>都能取到值。</p><p>解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于<code>undefined</code>和<code>null</code>无法转为对象,所以对它们进行解构赋值,都会报错。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> <span class="token punctuation">{</span> prop<span class="token operator">:</span> x <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token comment">// TypeError</span><span class="token keyword">let</span> <span class="token punctuation">{</span> prop<span class="token operator">:</span> y <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token comment">// TypeError</span></code></pre><h2 id="函数参数的解构赋值"><a href="#函数参数的解构赋值" class="headerlink" title="函数参数的解构赋值"></a>函数参数的解构赋值</h2><p>函数的参数也可以使用解构赋值。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">[</span>x<span class="token punctuation">,</span> y<span class="token punctuation">]</span></span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> x <span class="token operator">+</span> y<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span><span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">[</span>a<span class="token punctuation">,</span> b<span class="token punctuation">]</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> a <span class="token operator">+</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// [ 3, 7 ]</span>等价写法?函数参数的解构也可以使用默认值。<span class="token keyword">function</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">[</span>x<span class="token punctuation">,</span> y<span class="token operator">=</span><span class="token number">10</span><span class="token punctuation">]</span></span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> x <span class="token operator">+</span> y<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 11</span><span class="token keyword">function</span> <span class="token function">move</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span>x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> y <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">[</span>x<span class="token punctuation">,</span> y<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">move</span><span class="token punctuation">(</span><span class="token punctuation">{</span>x<span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> y<span class="token operator">:</span> <span class="token number">8</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [3, 8]</span><span class="token function">move</span><span class="token punctuation">(</span><span class="token punctuation">{</span>x<span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [3, 0]</span><span class="token function">move</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [0, 0]</span><span class="token function">move</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [0, 0]</span></code></pre><h2 id="圆括号问题"><a href="#圆括号问题" class="headerlink" title="圆括号问题"></a>圆括号问题</h2><p>解构赋值虽然很方便,但是解析起来并不容易。对于编译器来说,一个式子到底是模式,还是表达式,没有办法从一开始就知道,必须解析到(或解析不到)等号才能知道。</p><p>由此带来的问题是,如果模式中出现圆括号怎么处理。ES6 的规则是,只要有可能导致解构的歧义,就不得使用圆括号。</p><p>但是,这条规则实际上不那么容易辨别,处理起来相当麻烦。因此,建议只要有可能,就不要在模式中放置圆括号。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">{</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span>x<span class="token operator">:</span><span class="token number">1</span><span class="token punctuation">}</span></code></pre><h2 id="用途"><a href="#用途" class="headerlink" title="用途"></a>用途</h2><p>变量的解构赋值用途很多。</p><h3 id="(1)交换变量的值"><a href="#(1)交换变量的值" class="headerlink" title="(1)交换变量的值"></a><strong>(1)交换变量的值</strong></h3><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">let</span> y <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span><span class="token punctuation">[</span>x<span class="token punctuation">,</span> y<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span>y<span class="token punctuation">,</span> x<span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre><p>上面代码交换变量<code>x</code>和<code>y</code>的值,这样的写法不仅简洁,而且易读,语义非常清晰。</p><h3 id="(2)从函数返回多个值"><a href="#(2)从函数返回多个值" class="headerlink" title="(2)从函数返回多个值"></a><strong>(2)从函数返回多个值</strong></h3><p>函数能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回。有了解构赋值,取出这些值就非常方便。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 返回一个数组</span><span class="token keyword">function</span> <span class="token function">example</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">let</span> <span class="token punctuation">[</span>a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> c<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">example</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 返回一个对象</span><span class="token keyword">function</span> <span class="token function">example</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> foo<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> bar<span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">let</span> <span class="token punctuation">{</span> foo<span class="token punctuation">,</span> bar <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">example</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h3 id="(3)函数参数的定义"><a href="#(3)函数参数的定义" class="headerlink" title="(3)函数参数的定义"></a><strong>(3)函数参数的定义</strong></h3><p>解构赋值可以方便地将一组参数与变量名对应起来。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 参数是一组有次序的值</span><span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">[</span>x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z<span class="token punctuation">]</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token punctuation">}</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 参数是一组无次序的值</span><span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span>x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z<span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token punctuation">}</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">{</span>z<span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> y<span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> x<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h3 id="(4)提取-JSON-数据"><a href="#(4)提取-JSON-数据" class="headerlink" title="(4)提取 JSON 数据"></a><strong>(4)提取 JSON 数据</strong></h3><p>解构赋值对提取 JSON 对象中的数据,尤其有用。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> jsonData <span class="token operator">=</span> <span class="token punctuation">{</span> id<span class="token operator">:</span> <span class="token number">42</span><span class="token punctuation">,</span> status<span class="token operator">:</span> <span class="token string">"OK"</span><span class="token punctuation">,</span> data<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token number">867</span><span class="token punctuation">,</span> <span class="token number">5309</span><span class="token punctuation">]</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token keyword">let</span> <span class="token punctuation">{</span> id<span class="token punctuation">,</span> status<span class="token punctuation">,</span> data<span class="token operator">:</span> number <span class="token punctuation">}</span> <span class="token operator">=</span> jsonData<span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>id<span class="token punctuation">,</span> status<span class="token punctuation">,</span> number<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 42, "OK", [867, 5309]</span></code></pre><p>上面代码可以快速提取 JSON 数据的值。</p><h3 id="(5)函数参数的默认值"><a href="#(5)函数参数的默认值" class="headerlink" title="(5)函数参数的默认值"></a><strong>(5)函数参数的默认值</strong></h3><pre class="language-javascript" data-language="javascript"><code class="language-javascript">jQuery<span class="token punctuation">.</span><span class="token function-variable function">ajax</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span>url<span class="token punctuation">,</span> <span class="token punctuation">{</span> async <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token function-variable function">beforeSend</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> cache <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token function-variable function">complete</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> crossDomain <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">,</span> global <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token comment">// ... more config</span><span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ... do stuff</span><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre><p>指定参数的默认值,就避免了在函数体内部再写<code>var foo = config.foo || 'default foo';</code>这样的语句。</p><h3 id="(6)遍历-Map-结构"><a href="#(6)遍历-Map-结构" class="headerlink" title="(6)遍历 Map 结构"></a><strong>(6)遍历 Map 结构</strong></h3><p>任何部署了 Iterator 接口的对象,都可以用<code>for...of</code>循环遍历。Map 结构原生支持 Iterator 接口,配合变量的解构赋值,获取键名和键值就非常方便。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>map<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'first'</span><span class="token punctuation">,</span> <span class="token string">'hello'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>map<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'second'</span><span class="token punctuation">,</span> <span class="token string">'world'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> <span class="token punctuation">[</span>key<span class="token punctuation">,</span> value<span class="token punctuation">]</span> <span class="token keyword">of</span> map<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key <span class="token operator">+</span> <span class="token string">" is "</span> <span class="token operator">+</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">// first is hello</span><span class="token comment">// second is world</span></code></pre><p>如果只想获取键名,或者只想获取键值,可以写成下面这样。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 获取键名</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> <span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token keyword">of</span> map<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ...</span><span class="token punctuation">}</span><span class="token comment">// 获取键值</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> <span class="token punctuation">[</span><span class="token punctuation">,</span>value<span class="token punctuation">]</span> <span class="token keyword">of</span> map<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ...</span><span class="token punctuation">}</span></code></pre><h3 id="(7)输入模块的指定方法"><a href="#(7)输入模块的指定方法" class="headerlink" title="(7)输入模块的指定方法"></a><strong>(7)输入模块的指定方法</strong></h3><p>加载模块时,往往需要指定输入哪些方法。解构赋值使得输入语句非常清晰。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token punctuation">{</span> SourceMapConsumer<span class="token punctuation">,</span> SourceNode <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"source-map"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//加载进来的也是一个对象,本质,就是对象的解构赋值</span></code></pre><h1 id="函数扩展-amp-模板字符串"><a href="#函数扩展-amp-模板字符串" class="headerlink" title="函数扩展&模板字符串"></a>函数扩展&模板字符串</h1><h2 id="目标"><a href="#目标" class="headerlink" title="目标"></a>目标</h2><ul><li>模版字符串</li><li>函数参数 的默认值</li><li>rest参数</li><li>箭头函数</li></ul><h2 id="模版字符串"><a href="#模版字符串" class="headerlink" title="模版字符串"></a>模版字符串</h2><p>在传统javascript中,输出模版通常是字符串拼接的形式,如下:</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span><span class="token string">'铁柱'</span><span class="token punctuation">,</span> age<span class="token operator">:</span><span class="token number">45</span><span class="token punctuation">,</span> job<span class="token operator">:</span><span class="token string">'不会写代码的铁匠不是一个合格的干饭人,请问我的工作是什么'</span><span class="token punctuation">}</span><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">'<ul><li>我叫:'</span><span class="token operator">+</span>person<span class="token punctuation">.</span>name<span class="token operator">+</span><span class="token string">'</li></li>我今年:'</span><span class="token operator">+</span>person<span class="token punctuation">.</span>age<span class="token operator">+</span><span class="token string">'</li><li>我的工作:'</span><span class="token operator">+</span>person<span class="token punctuation">.</span>job<span class="token operator">+</span><span class="token string">'<li></ul>'</span><span class="token punctuation">;</span>缺点:写法繁琐,不好维护,使用不方便;改进方案:<span class="token constant">ES6</span>中,引入模版字符串,来解决此问题;</code></pre><p>ES6中用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">//普通自字符串</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">javaScript String</span><span class="token template-punctuation string">`</span></span><span class="token comment">//多行字符串</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">It's a fine day todayLet's study together</span><span class="token template-punctuation string">`</span></span><span class="token comment">//在字符串中嵌入变量,需要将变量名写在${}之中</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"><ul><li>我叫:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>person<span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"></li><li>我今年:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>person<span class="token punctuation">.</span>age<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"></li><li>我的工作:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>person<span class="token punctuation">.</span>job<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"></li></ul></span><span class="token template-punctuation string">`</span></span><span class="token comment">//大括号内部可以放入任意的 JavaScript 表达式,可以进行运算,以及引用对象属性。</span><span class="token comment">//模板字符串之中还能调用函数</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">今天是:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">let</span> y <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>x<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> + </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>y <span class="token operator">*</span> <span class="token number">2</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> = </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>x <span class="token operator">+</span> y <span class="token operator">*</span> <span class="token number">2</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token comment">// "1 + 4 = 5"</span></code></pre><h2 id="函数参数的默认值"><a href="#函数参数的默认值" class="headerlink" title="函数参数的默认值"></a>函数参数的默认值</h2><p>ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">,</span>b<span class="token operator">=</span><span class="token number">1</span></span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">return</span> a<span class="token operator">+</span>b<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//2</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//3</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token comment">//21</span></code></pre><p>ES6之前函数参数默认值的实现:</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span>b</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> a<span class="token operator">+</span>b<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//NaN</span><span class="token keyword">function</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span>b</span><span class="token punctuation">)</span><span class="token punctuation">{</span> a <span class="token operator">=</span> a <span class="token operator">||</span> <span class="token number">1</span><span class="token punctuation">;</span> b <span class="token operator">=</span> b <span class="token operator">||</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">return</span> a<span class="token operator">+</span>b<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//2</span><span class="token comment">//传参,但是传参时对应的布尔值为false,则赋值不起作用</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token comment">// 3 原因是0在做 || 运算时,被对应转成了false, 所以默认值 1 起作用了。 可以尝试 '' ,undefined,null 等</span>优化:<span class="token keyword">function</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span>b</span><span class="token punctuation">)</span><span class="token punctuation">{</span> a <span class="token operator">=</span> <span class="token keyword">typeof</span> a<span class="token operator">==</span><span class="token string">'undefined'</span><span class="token operator">?</span><span class="token number">1</span><span class="token operator">:</span>a<span class="token punctuation">;</span> b <span class="token operator">=</span> <span class="token keyword">typeof</span> b<span class="token operator">==</span><span class="token string">'undefined'</span><span class="token operator">?</span><span class="token number">1</span><span class="token operator">:</span>b<span class="token punctuation">;</span> <span class="token keyword">return</span> a<span class="token operator">+</span>b<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//2</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token comment">//3</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//3 依然存在问题,所以推荐使用ES6中的函数参数默认值</span></code></pre><p>与解构赋值默认值结合使用(回顾上一章节)</p><h2 id="rest参数"><a href="#rest参数" class="headerlink" title="rest参数"></a>rest参数</h2><p>ES6 引入 rest 参数(形式为<code>...变量名</code>),用于获取函数的多余参数(…运算符,剩余运算符的用法),这样就不需要使用<code>arguments</code>对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>arg</span><span class="token punctuation">)</span><span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arg<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//[1,2,3,4,5]</span> <span class="token keyword">let</span> sum <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> arg<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span><span class="token punctuation">{</span> sum<span class="token operator">+=</span>item<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> sum<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//15</span><span class="token comment">//注意,rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错。</span></code></pre><p>补充arguments</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">//arguments对象是所有(非箭头)函数中都可用的局部变量。</span><span class="token comment">//你可以使用arguments对象在函数中引用函数的参数。此对象包含传递给函数的每个参数,第一个参数在索引0处。</span><span class="token comment">//是一个对应函数参数的类数组对象。不是一个真正的数组。无法使用数组的方法</span><span class="token keyword">function</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arguments<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token class-name">Array</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>arguments<span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> sum <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> arr<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span><span class="token punctuation">{</span> sum<span class="token operator">+=</span>item<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sum<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> sum<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h2 id="call-amp-apply-amp-bind"><a href="#call-amp-apply-amp-bind" class="headerlink" title="call & apply & bind"></a>call & apply & bind</h2><p>Function函数运行时存在内部指针对象this,根据函数的调用情况不同,this的指向也不同。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token number">1.</span>作为Dom对象的事件处理函数,使用<span class="token keyword">this</span>时,<span class="token keyword">this</span>指向当前Dom对象<span class="token number">2.</span>作为对象的方法使用时,<span class="token keyword">this</span>指向当前对象<span class="token number">3.</span>作为构造函数使用时,<span class="token keyword">this</span>指向当前构造函数所实例化出来的对象<span class="token number">4.</span>在函数嵌套时,内层函数不会继承外城函数<span class="token keyword">this</span>的指向。 <span class="token operator">--</span> 如果想让内层函数,使用外层函数<span class="token keyword">this</span>指向时,可以在外层函数中用一个变量(that)保存<span class="token keyword">this</span>。 <span class="token operator">--</span>由于作用域链的原因,that对于内层函数是可见的<span class="token number">5.</span>作为全局函数使用<span class="token keyword">this</span>时,<span class="token keyword">this</span>指向window<span class="token punctuation">;</span></code></pre><p>当然Function函数的this也是可以改变的。而call,apply,bind等函数,就是为了改变函数this指向而存在的。</p><p>每个javaScript函数都是一个对象,而这个对象的构造函数是Function,它有prototype属性指向原型对象,原型对象上挂有call、apply、bind等方法;</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> Cat <span class="token operator">=</span> <span class="token punctuation">{</span>eat<span class="token operator">:</span><span class="token string">'fish'</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">Dog</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>eat <span class="token operator">=</span> <span class="token string">'bone'</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token class-name">Dog</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">say</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>eat<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">let</span> dog <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Dog</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>dog<span class="token punctuation">.</span><span class="token function">say</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//bone</span><span class="token class-name">Dog</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function">say</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>Cat<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//fish</span>dog<span class="token punctuation">.</span><span class="token function">say</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>Cat<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//fish</span><span class="token comment">//注意:call 、apply 可以实现类的继承</span></code></pre><p>区别:</p><p>相同点:两个方法产生的作用是完全一样的不同点:方法传递的参数不同<br>call接受的是一个参数列表,而apply()接受一个参数数组。 func.call(this, arg1, arg2);<br>func.apply(this,[arg1, arg2])<br>其中this是你想指定的上下文,他可以是任何一个JavaScript对象(JavaScript中一切皆对象),call需要把参数按顺序传递进去,而apply则是把参数放在数组里。</p><p>bind()方法也是可以改变函数体内this的指向。<br>bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入bind(方法的第一个参数作为this,传入bind()方法的第二个以及以后的参数,加上绑定函数运行时本身的参数,按照顺序作为原函数的参数来调用原函数。(就是与call使用方式一样,只是bind不会立即执行)<br>也就是说,区别是,当你希望改变this指向之后并非立即执行,使用bind()方法。而apply/call则会立即执行函数</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> dog_bind <span class="token operator">=</span> dog<span class="token punctuation">.</span><span class="token function">say</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>Cat<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">dog_bind</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h2 id="箭头函数"><a href="#箭头函数" class="headerlink" title="箭头函数"></a><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions">箭头函数</a></h2><h3 id="基本用法-4"><a href="#基本用法-4" class="headerlink" title="基本用法"></a>基本用法</h3><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">//ES6 允许使用“箭头”(=>)定义函数。</span><span class="token keyword">var</span> <span class="token function-variable function">f</span> <span class="token operator">=</span> <span class="token parameter">v</span> <span class="token operator">=></span> v<span class="token punctuation">;</span><span class="token comment">// 等同于</span><span class="token keyword">var</span> <span class="token function-variable function">f</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">v</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> v<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">//如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。</span><span class="token comment">//如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。</span><span class="token comment">//由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。</span><span class="token comment">//箭头函数可以与变量解构结合使用。</span><span class="token comment">//箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。</span></code></pre><h3 id="使用注意点"><a href="#使用注意点" class="headerlink" title="使用注意点"></a>使用注意点</h3><p>(1)函数体内的<code>this</code>对象,就是定义时所在的对象,而不是使用时所在的对象。</p><p>(2)不可以当作构造函数,也就是说,不可以使用<code>new</code>命令,否则会抛出一个错误。</p><p>(3)不可以使用<code>arguments</code>对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。</p><p> (4) 箭头函数没有<code>prototype</code>属性。</p><h3 id="箭头函数的this"><a href="#箭头函数的this" class="headerlink" title="箭头函数的this"></a>箭头函数的this</h3><ul><li>箭头函数不会创建自己的<code>this,但是可以使用(继承)</code></li><li>它只会从自己的作用域链的上一层继承this</li><li>涉及到函数嵌套,内层的箭头函数的this, 继承于父级</li><li>如果没有函数嵌套,箭头函数中的this,指向window</li></ul><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">//code_one</span><span class="token keyword">var</span> name_ <span class="token operator">=</span> <span class="token string">'阿黄'</span><span class="token punctuation">;</span> <span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> name_<span class="token operator">:</span> <span class="token string">"ergou"</span><span class="token punctuation">,</span> <span class="token function-variable function">sayname_1</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name_<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'0.0.0.0.0::::::'</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name_<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function-variable function">sayname_2</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>window<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name_<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'1.1.1.1.1.1::::::'</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name_<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token comment">//code_two</span> document<span class="token punctuation">.</span><span class="token function">getElementsByTagName</span><span class="token punctuation">(</span><span class="token string">'button'</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function-variable function">onclick</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> document<span class="token punctuation">.</span><span class="token function">getElementsByTagName</span><span class="token punctuation">(</span><span class="token string">'button'</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function-variable function">onclick</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre><h1 id="set-amp-map-数据结构"><a href="#set-amp-map-数据结构" class="headerlink" title="set & map 数据结构"></a>set & map 数据结构</h1><p>在ES6之前,存储大量数据时,常用的数据结构就是 数组 ,对象, 或者是数组对象嵌套使用。 </p><p>在es6 中,新增了两个新的数据结构,– set – map</p><h2 id="Set数据结构"><a href="#Set数据结构" class="headerlink" title="Set数据结构"></a>Set数据结构</h2><p>基本用法:</p><ul><li><p>ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。</p></li><li><p><code>Set</code>本身是一个构造函数,用来生成 Set 数据结构</p></li><li><p><code>Set</code>函数可以接受一个数组作为参数(或者具有 iterable 接口的其他数据结构),用来初始化。</p></li><li><p>```js<br>let my_set = new Set();<br>my_set.add(‘a’);<br>my_set.add(‘a’);<br>[…my_set];//[‘a’]</p><p>let arr = [1, 2, 3, 2, 2, 5, 8, 4, 5, 87, 1, 2, 5, 5];<br>let s = new Set(arr);</p><p>// 去除数组的重复成员<br>[…new Set(array)]</p><p>//去除字符串里面的重复字符<br>[…new Set(‘ababbc’)].join(‘’)<br>// “abc”</p><pre class="language-none"><code class="language-none">## Set实例的属性和方法Set 结构的实例有以下属性。- `Set.prototype.constructor`:构造函数,默认就是`Set`函数。- `Set.prototype.size`:返回`Set`实例的成员总数。Set 实例的方法分为两大类:操作方法(用于操作数据)和遍历方法(用于遍历成员)。### 操作方法- `Set.prototype.add(value)`:添加某个值,返回 Set 结构本身。- `Set.prototype.delete(value)`:删除某个值,返回一个布尔值,表示删除是否成功。- `Set.prototype.has(value)`:返回一个布尔值,表示该值是否为`Set`的成员。- `Set.prototype.clear()`:清除所有成员,没有返回值。### 遍历方法- `Set.prototype.keys()`:返回键名的遍历器对象- `Set.prototype.values()`:返回键值的遍历器对象- `Set.prototype.entries()`:返回键值对的遍历器对象- `Set.prototype.forEach()`:使用回调函数遍历每个成员## Map数据结构### 基本用法:ES6之前,对象以键值对来保存数据时,键只能是字符串,这给他带来啦很大的限制```jsconst data = {};const element = document.getElementById('myDiv');data[element] = 'metadata';data['[object HTMLDivElement]'] // "metadata"//由于对象只接受字符串作为键名,所以element被自动转为字符串[object HTMLDivElement]。</code></pre></li></ul><p>为了解决这个问题,ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">//构造函数Map</span><span class="token keyword">let</span> myMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>m<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>div_<span class="token punctuation">,</span><span class="token string">'哈哈哈哈'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>m<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">,</span><span class="token string">'嘿嘿'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>m<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//作为构造函数,Map 也可以接受一个数组作为参数。</span><span class="token comment">// 该数组的成员是一个个表示键值对的数组。</span><span class="token keyword">let</span> m <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token string">"key"</span><span class="token punctuation">,</span><span class="token string">"value"</span><span class="token punctuation">]</span><span class="token punctuation">,</span><span class="token punctuation">[</span><span class="token string">"num"</span><span class="token punctuation">,</span><span class="token string">"000001"</span><span class="token punctuation">]</span><span class="token punctuation">,</span><span class="token punctuation">[</span><span class="token string">"age"</span><span class="token punctuation">,</span><span class="token number">120</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>m<span class="token punctuation">,</span>m<span class="token punctuation">.</span>size<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h3 id="Map-结构的实例有以下属性和操作方法。"><a href="#Map-结构的实例有以下属性和操作方法。" class="headerlink" title="Map 结构的实例有以下属性和操作方法。"></a>Map 结构的实例有以下属性和操作方法。</h3><ul><li><code>size</code>属性返回 Map 结构的成员总数。</li><li><strong>Map.prototype.set(key, value)</strong><ul><li><code>set</code>方法设置键名<code>key</code>对应的键值为<code>value</code>,然后返回整个 Map 结构。如果<code>key</code>已经有值,则键值会被更新,否则就新生成该键。</li></ul></li><li><strong>Map.prototype.get(key)</strong><ul><li> <code>get</code>方法读取<code>key</code>对应的键值,如果找不到<code>key</code>,返回<code>undefined</code>。</li></ul></li><li><strong>Map.prototype.has(key)</strong><ul><li><code>has</code>方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。</li></ul></li><li><strong>Map.prototype.delete(key)</strong><ul><li><code>delete</code>方法删除某个键,返回<code>true</code>。如果删除失败,返回<code>false</code>。</li></ul></li><li><strong>Map.prototype.clear()</strong><ul><li><code>clear</code>方法清除所有成员,没有返回值。</li></ul></li></ul><h3 id="遍历方法"><a href="#遍历方法" class="headerlink" title="遍历方法"></a>遍历方法</h3><p>Map 结构原生提供三个遍历器生成函数和一个遍历方法。</p><ul><li><code>Map.prototype.keys()</code>:返回键名的遍历器。</li><li><code>Map.prototype.values()</code>:返回键值的遍历器。</li><li><code>Map.prototype.entries()</code>:返回所有成员的遍历器。</li><li><code>Map.prototype.forEach()</code>:遍历 Map 的所有成员。</li></ul><h3 id="与其他数据结构的互相转换"><a href="#与其他数据结构的互相转换" class="headerlink" title="与其他数据结构的互相转换"></a>与其他数据结构的互相转换</h3><p><strong>(1)Map 转为数组</strong></p><p>前面已经提过,Map 转为数组最方便的方法,就是使用扩展运算符(<code>...</code>)。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> myMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token punctuation">{</span>foo<span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'abc'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">[</span><span class="token operator">...</span>myMap<span class="token punctuation">]</span><span class="token comment">// [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]</span></code></pre><p><strong>(2)数组 转为 Map</strong></p><p>将数组传入 Map 构造函数,就可以转为 Map。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">{</span>foo<span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'abc'</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token comment">// Map {</span><span class="token comment">// true => 7,</span><span class="token comment">// Object {foo: 3} => ['abc']</span><span class="token comment">// }</span></code></pre><p><strong>(3)Map 转为对象</strong></p><p>如果所有 Map 的键都是字符串,它可以无损地转为对象。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">strMapToObj</span><span class="token punctuation">(</span><span class="token parameter">strMap</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> obj <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> <span class="token punctuation">[</span>k<span class="token punctuation">,</span>v<span class="token punctuation">]</span> <span class="token keyword">of</span> strMap<span class="token punctuation">)</span> <span class="token punctuation">{</span> obj<span class="token punctuation">[</span>k<span class="token punctuation">]</span> <span class="token operator">=</span> v<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> obj<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">const</span> myMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'yes'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'no'</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">strMapToObj</span><span class="token punctuation">(</span>myMap<span class="token punctuation">)</span><span class="token comment">// { yes: true, no: false }</span></code></pre><p>如果有非字符串的键名,那么这个键名会被转成字符串,再作为对象的键名。</p><p><strong>(4)对象转为 Map</strong></p><p>对象转为 Map 可以通过<code>Object.entries()</code>。 Object.keys() //返回对象的键名 Object.entries() //返回对象的键值对</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token string">"a"</span><span class="token operator">:</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token operator">:</span><span class="token number">2</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token keyword">let</span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">entries</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>此外,也可以自己实现一个转换函数。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">objToStrMap</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> strMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> k <span class="token keyword">of</span> Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> strMap<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>k<span class="token punctuation">,</span> obj<span class="token punctuation">[</span>k<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> strMap<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">objToStrMap</span><span class="token punctuation">(</span><span class="token punctuation">{</span>yes<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> no<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token comment">// Map {"yes" => true, "no" => false}</span></code></pre><p><strong>(5)Map 转为 JSON</strong></p><p>Map 转为 JSON 要区分两种情况。一种情况是,Map 的键名都是字符串,这时可以选择转为对象 JSON。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript">map<span class="token operator">==</span><span class="token operator">></span>obj<span class="token operator">==</span><span class="token operator">></span>json<span class="token keyword">function</span> <span class="token function">strMapToJson</span><span class="token punctuation">(</span><span class="token parameter">strMap</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span><span class="token function">strMapToObj</span><span class="token punctuation">(</span>strMap<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">let</span> myMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'yes'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'no'</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">strMapToJson</span><span class="token punctuation">(</span>myMap<span class="token punctuation">)</span><span class="token comment">// '{"yes":true,"no":false}'</span></code></pre><p>另一种情况是,Map 的键名有非字符串,这时可以选择转为数组 JSON。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">mapToArrayJson</span><span class="token punctuation">(</span><span class="token parameter">map</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">...</span>map<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">let</span> myMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token punctuation">{</span>foo<span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'abc'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">mapToArrayJson</span><span class="token punctuation">(</span>myMap<span class="token punctuation">)</span><span class="token comment">// '[[true,7],[{"foo":3},["abc"]]]'</span></code></pre><p><strong>(6)JSON 转为 Map</strong></p><p>JSON 转为 Map,正常情况下,所有键名都是字符串。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript">jsonString <span class="token operator">==</span> <span class="token operator">></span> obj <span class="token operator">==</span><span class="token operator">></span> map<span class="token keyword">function</span> <span class="token function">jsonToStrMap</span><span class="token punctuation">(</span><span class="token parameter">jsonStr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">objToStrMap</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>jsonStr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">jsonToStrMap</span><span class="token punctuation">(</span><span class="token string">'{"yes": true, "no": false}'</span><span class="token punctuation">)</span><span class="token comment">// Map {'yes' => true, 'no' => false}</span></code></pre><h1 id="Proxy-代理拦截操作"><a href="#Proxy-代理拦截操作" class="headerlink" title="Proxy(代理拦截操作)"></a>Proxy(代理拦截操作)</h1><p>Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。</p><p><img src="assets/image-20201203225226112.png" alt="image-20201203225226112" loading="lazy"></p><pre class="language-js" data-language="js"><code class="language-js"><span class="token constant">ES6</span> 原生提供 Proxy 构造函数,用来生成 Proxy 实例。<span class="token keyword">var</span> proxy <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Proxy</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span>Proxy 对象的所有用法,都是上面这种形式,不同的只是handler参数的写法。其中,<span class="token keyword">new</span> <span class="token class-name">Proxy</span><span class="token punctuation">(</span><span class="token punctuation">)</span>表示生成一个Proxy实例,target参数表示所要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为。<span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> sex<span class="token operator">:</span><span class="token string">'man'</span><span class="token punctuation">}</span><span class="token keyword">let</span> myproxy <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Proxy</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span><span class="token punctuation">{</span> <span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">set</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">has</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">delteProperty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token operator">...</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h2 id="Proxy-支持的拦截操作一览,一共-13-种。"><a href="#Proxy-支持的拦截操作一览,一共-13-种。" class="headerlink" title="Proxy 支持的拦截操作一览,一共 13 种。"></a>Proxy 支持的拦截操作一览,一共 13 种。</h2><ul><li>**get(target, propKey, receiver)**:拦截对象属性的读取,比如<code>proxy.foo</code>和<code>proxy['foo']</code>。</li><li>**set(target, propKey, value, receiver)**:拦截对象属性的设置,比如<code>proxy.foo = v</code>或<code>proxy['foo'] = v</code>,返回一个布尔值。</li><li>**has(target, propKey)**:拦截<code>propKey in proxy</code>的操作,返回一个布尔值。</li><li>**deleteProperty(target, propKey)**:拦截<code>delete proxy[propKey]</code>的操作,返回一个布尔值。</li><li>**ownKeys(target)**:拦截<code>Object.getOwnPropertyNames(proxy)</code>、<code>Object.getOwnPropertySymbols(proxy)</code>、<code>Object.keys(proxy)</code>、<code>for...in</code>循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而<code>Object.keys()</code>的返回结果仅包括目标对象自身的可遍历属性。</li><li>**getOwnPropertyDescriptor(target, propKey)**:拦截<code>Object.getOwnPropertyDescriptor(proxy, propKey)</code>,返回属性的描述对象。</li><li>**defineProperty(target, propKey, propDesc)**:拦截<code>Object.defineProperty(proxy, propKey, propDesc)</code>、<code>Object.defineProperties(proxy, propDescs)</code>,返回一个布尔值。</li><li>**preventExtensions(target)**:拦截<code>Object.preventExtensions(proxy)</code>,返回一个布尔值。</li><li>**getPrototypeOf(target)**:拦截<code>Object.getPrototypeOf(proxy)</code>,返回一个对象。</li><li>**isExtensible(target)**:拦截<code>Object.isExtensible(proxy)</code>,返回一个布尔值。</li><li>**setPrototypeOf(target, proto)**:拦截<code>Object.setPrototypeOf(proxy, proto)</code>,返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。</li><li>**apply(target, object, args)**:拦截 Proxy 实例作为函数调用的操作,比如<code>proxy(...args)</code>、<code>proxy.call(object, ...args)</code>、<code>proxy.apply(...)</code>。</li><li>**construct(target, args)**:拦截 Proxy 实例作为构造函数调用的操作,比如<code>new proxy(...args)</code>。</li></ul><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> handler <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">defineProperty</span> <span class="token punctuation">(</span><span class="token parameter">target<span class="token punctuation">,</span> key<span class="token punctuation">,</span> descriptor</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token keyword">var</span> target <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token keyword">var</span> proxy <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Proxy</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span>proxy<span class="token punctuation">.</span>foo <span class="token operator">=</span> <span class="token string">'bar'</span> <span class="token comment">// 不会生效</span></code></pre><h2 id="Object-defineProperty"><a href="#Object-defineProperty" class="headerlink" title="Object.defineProperty()"></a><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty">Object.defineProperty()</a></h2><p>Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。</p><p>vue实现数据双向绑定主要是:采<strong>用数据劫持结合发布者-订阅者模式</strong>的方式,通过 <code>Object.defineProperty()</code> 来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调</p><h3 id="语法"><a href="#语法" class="headerlink" title="语法"></a>语法</h3><pre class="language-js" data-language="js"><code class="language-js">Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> prop<span class="token punctuation">,</span> descriptor<span class="token punctuation">)</span></code></pre><h3 id="参数"><a href="#参数" class="headerlink" title="参数"></a>参数</h3><pre class="language-none"><code class="language-none">obj</code></pre><p>要定义属性的对象。</p><pre class="language-none"><code class="language-none">prop</code></pre><p>要定义或修改的属性的名称或 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol"><code>Symbol</code></a> 。</p><pre class="language-none"><code class="language-none">descriptor</code></pre><p>要定义或修改的属性描述符。</p><h3 id="返回值"><a href="#返回值" class="headerlink" title="返回值"></a>返回值</h3><p>被传递给函数的对象。</p><h3 id="描述符(descriptor)"><a href="#描述符(descriptor)" class="headerlink" title="描述符(descriptor)"></a>描述符(descriptor)</h3><p>对象里目前存在的属性描述符有两种主要形式:<em>数据描述符</em>和<em>存取描述符</em>。<em>数据描述符</em>是一个具有值的属性,该值可以是可写的,也可以是不可写的。<em>存取描述符</em>是由 getter 函数和 setter 函数所描述的属性。一个描述符只能是这两者其中之一;不能同时是两者。</p><p>这两种描述符都是对象。它们共享以下可选键值</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">//*数据描述符*</span>configurable当且仅当该属性的 configurable 键值为 <span class="token boolean">true</span> 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 <span class="token boolean">false</span>。enumerable当且仅当该属性的 enumerable 键值为 <span class="token boolean">true</span> 时,该属性才会出现在对象的枚举属性中。在枚举对象属性时会被枚举到(<span class="token keyword">for</span><span class="token operator">...</span><span class="token keyword">in</span> 或 Object<span class="token punctuation">.</span>keys 方法)默认为 <span class="token boolean">false</span>。数据描述符还具有以下可选键值:value该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 <span class="token keyword">undefined</span>。writable当且仅当该属性的 writable 键值为 <span class="token boolean">true</span> 时,属性的值,也就是上面的 value,才能被赋值运算符改变。默认为 <span class="token boolean">false</span>。存取描述符还具有以下可选键值:<span class="token comment">//*存取描述符*</span><span class="token keyword">get</span>属性的 getter 函数,如果没有 getter,则为 <span class="token keyword">undefined</span>。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 <span class="token keyword">this</span> 对象(由于继承关系,这里的<span class="token keyword">this</span>并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。默认为 <span class="token keyword">undefined</span>。<span class="token keyword">set</span>属性的 setter 函数,如果没有 setter,则为 <span class="token keyword">undefined</span>。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 <span class="token keyword">this</span> 对象。默认为 <span class="token keyword">undefined</span>。<span class="token comment">//描述符默认值汇总</span>拥有布尔值的键 configurable、enumerable 和 writable 的默认值都是 <span class="token boolean">false</span>。属性值和函数的键 value、<span class="token keyword">get</span> 和 <span class="token keyword">set</span> 字段的默认值为 <span class="token keyword">undefined</span>。<span class="token comment">//描述符可拥有的键值</span> configurableenumerablevaluewritable<span class="token keyword">get</span> <span class="token keyword">set</span>数据描述符 可以 可以 可以 可以 不可以不可以存取描述符 可以 可以 不可以 不可以 可以 可以</code></pre><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span><span class="token string">'name'</span><span class="token punctuation">,</span><span class="token punctuation">{</span> <span class="token comment">// value:'nihao',</span> <span class="token comment">// writable:false,</span> <span class="token comment">// enumerable:true,</span> <span class="token comment">// configurable:true</span> <span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> d<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">set</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span><span class="token punctuation">{</span> d <span class="token operator">=</span> v<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span><span class="token string">'age'</span><span class="token punctuation">,</span><span class="token punctuation">{</span> value<span class="token operator">:</span><span class="token string">'12'</span><span class="token punctuation">,</span> writable<span class="token operator">:</span><span class="token boolean">false</span><span class="token punctuation">,</span> enumerable<span class="token operator">:</span><span class="token boolean">true</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h1 id="Promise-异步编程解决方案"><a href="#Promise-异步编程解决方案" class="headerlink" title="Promise(异步编程解决方案)"></a>Promise(异步编程解决方案)</h1><h2 id="回调地狱"><a href="#回调地狱" class="headerlink" title="回调地狱"></a>回调地狱</h2><pre class="language-js" data-language="js"><code class="language-js">假设场景:获取学生成绩,并划分等级。提供一些数据接口,接口数据嵌套,下一个接口数据依赖于上一个接口的返回值学校 <span class="token operator">===</span><span class="token operator">></span>班级 <span class="token operator">===</span><span class="token operator">></span> 学生 <span class="token operator">===</span><span class="token operator">></span> 成绩 <span class="token operator">===</span><span class="token operator">></span> 等级的划分<span class="token comment">//学校信息接口:http://xxxx.school.com/info?id='00001'; </span>返回值<span class="token operator">:</span><span class="token punctuation">[</span><span class="token punctuation">{</span>className<span class="token operator">:</span><span class="token string">'三年级2班'</span><span class="token punctuation">,</span>classId<span class="token operator">:</span><span class="token string">'c00001'</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token operator">...</span><span class="token punctuation">]</span><span class="token comment">//班级信息接口:http://xxxx.class_info.com/info?classId = classId</span>$<span class="token punctuation">.</span><span class="token function">ajax</span><span class="token punctuation">(</span><span class="token punctuation">{</span> url<span class="token operator">:</span><span class="token string">''</span><span class="token punctuation">,</span> data<span class="token operator">:</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function-variable function">success</span><span class="token operator">:</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span><span class="token punctuation">{</span> $<span class="token punctuation">.</span><span class="token function">ajax</span><span class="token punctuation">(</span><span class="token punctuation">{</span> url<span class="token operator">:</span><span class="token string">''</span><span class="token punctuation">,</span> data<span class="token operator">:</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function-variable function">success</span><span class="token operator">:</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span><span class="token punctuation">{</span>$<span class="token punctuation">.</span><span class="token function">ajax</span><span class="token punctuation">(</span><span class="token punctuation">{</span> url<span class="token operator">:</span><span class="token string">''</span><span class="token punctuation">,</span> data<span class="token operator">:</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function-variable function">success</span><span class="token operator">:</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>回调地狱:回调地狱最主要的就是因为功能逻辑代码嵌套的层次太多<span class="token punctuation">,</span>导致可读性降低<span class="token punctuation">,</span>维护困难,对代码性能,以及易读性,不友好。案例:jq_ajax请求的回调嵌套</code></pre><h2 id="Promise-的含义"><a href="#Promise-的含义" class="headerlink" title="Promise 的含义"></a>Promise 的含义</h2><p>Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了<code>Promise</code>对象。所谓<code>Promise</code>,简单说就是一个容器,里面管理着异步的操作,从它可以获取异步操作的消息.本身不是异步的,是里面管理的操作是异步的。</p><p><code>Promise</code>对象有以下两个特点。</p><p>(1)对象的状态不受外界影响。<code>Promise</code>对象代表一个异步操作,有三种状态:<code>pending</code>(进行中)、<code>fulfilled</code>(已成功)和<code>rejected</code>(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是<code>Promise</code>这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。</p><p>(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。<code>Promise</code>对象的状态改变,只有两种可能:从<code>pending</code>变为<code>fulfilled</code>和从<code>pending</code>变为<code>rejected</code>。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对<code>Promise</code>对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。</p><p>有了<code>Promise</code>对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,<code>Promise</code>对象提供统一的接口,使得控制异步操作更加容易。</p><p><code>Promise</code>也有一些缺点。首先,无法取消<code>Promise</code>,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,<code>Promise</code>内部抛出的错误,不会反应到外部。第三,当处于<code>pending</code>状态时,无法得知目前进展到哪一个阶段</p><h2 id="基本用法-5"><a href="#基本用法-5" class="headerlink" title="基本用法"></a>基本用法</h2><h3 id="定义"><a href="#定义" class="headerlink" title="定义"></a>定义</h3><p>S6 规定,<code>Promise</code>对象是一个构造函数,用来生成<code>Promise</code>实例。</p><pre class="language-js" data-language="js"><code class="language-js">promise 是一个构造函数,需要实例化对象promise构造函数,接受一个函数作为参数作为参数的函数也接受两个参数,分别是:<span class="token operator">--</span> resolve <span class="token operator">--</span> reject<span class="token operator">--</span> 它们是两个函数,由 JavaScript 引擎提供,不用自己部署。<span class="token operator">--</span>resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;<span class="token operator">--</span>reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。<span class="token keyword">let</span> mypromise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span>reject</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token comment">// resolve();</span><span class="token comment">// reject();</span><span class="token keyword">if</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span>username<span class="token operator">:</span><span class="token string">'张好人'</span><span class="token punctuation">,</span>age<span class="token operator">:</span><span class="token number">22</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token function">resolve</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">else</span><span class="token punctuation">{</span><span class="token function">reject</span><span class="token punctuation">(</span><span class="token string">'error'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> resolve <span class="token punctuation">,</span>reject <span class="token function">抛出数据以后,使用then</span><span class="token punctuation">(</span><span class="token punctuation">)</span> 来接收 <span class="token function">(promise实例对象下有个then</span><span class="token punctuation">(</span><span class="token punctuation">)</span>) mypromise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>fn1<span class="token punctuation">,</span>fn2<span class="token punctuation">)</span><span class="token punctuation">;</span>fn1 <span class="token operator">===</span><span class="token operator">></span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">//用来接收成功状态时的数据</span>fn2 <span class="token operator">===</span><span class="token operator">></span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">//用来接收失败状态时的数据</span></code></pre><h3 id="demo-one"><a href="#demo-one" class="headerlink" title="demo_one"></a>demo_one</h3><pre class="language-js" data-language="js"><code class="language-js">下面是一个Promise对象的简单例子。<span class="token keyword">function</span> <span class="token function">timeout</span><span class="token punctuation">(</span><span class="token parameter">ms</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span>reject</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{</span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token string">'done'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>ms<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">timeout</span><span class="token punctuation">(</span><span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">r</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>r<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">r</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>r<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> 上面代码中,timeout方法返回一个Promise实例,表示一段时间以后才会发生的结果。过了指定的时间(ms参数)以后,Promise实例的状态变为resolved,就会触发then方法绑定的回调函数。</code></pre><h3 id="demo-two"><a href="#demo-two" class="headerlink" title="demo_two"></a>demo_two</h3><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">// Promise 新建后就会立即执行</span> <span class="token keyword">let</span> promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Promise'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//1</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'resolved.'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//3</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Hi!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//2</span></code></pre><h3 id="Promise-prototype-then"><a href="#Promise-prototype-then" class="headerlink" title="Promise.prototype.then"></a>Promise.prototype.then</h3><p>它的作用是为 Promise 实例添加状态改变时的回调函数。<code>then</code>方法的第一个参数是<code>resolved</code>状态的回调函数,第二个参数(可选)是<code>rejected</code>状态的回调函数。<code>then</code>方法返回的是一个新的<code>Promise</code>实例(注意,不是原来那个<code>Promise</code>实例)。因此可以采用链式写法,即<code>then</code>方法后面再调用另一个<code>then</code>方法。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span>reject</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token string">'000'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token keyword">else</span><span class="token punctuation">{</span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token string">'1111'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">re</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>re<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">er</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>er<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token string">'....'</span><span class="token punctuation">}</span><span class="token punctuation">)</span></code></pre><h3 id="Promise-prototype-catch"><a href="#Promise-prototype-catch" class="headerlink" title="Promise.prototype.catch()"></a>Promise.prototype.catch()</h3><p><code>Promise.prototype.catch()</code>方法是<code>.then(null, rejection)</code>或<code>.then(undefined, rejection)</code>的别名,用于指定发生错误时的回调函数。</p><p>如果Promise 对象对象状态变为<code>resolved</code>,则会调用<code>then()</code>方法指定的回调函数;如果异步操作抛出错误,状态就会变为<code>rejected</code>,就会调用<code>catch()</code>方法指定的回调函数,处理这个错误。另外,<code>then()</code>方法指定的回调函数,如果运行中抛出错误,也会被<code>catch()</code>方法捕获。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span>reject</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token string">'ok'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token keyword">else</span><span class="token punctuation">{</span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token string">'err'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">er</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>er<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h3 id="promise-all-race"><a href="#promise-all-race" class="headerlink" title="promise.all / race"></a>promise.all / race</h3><pre class="language-none"><code class="language-none">//异步加载图片案例// Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例// let proall = Promise.all([p1,p2,....]);1)只有p1、p2、p3的状态都变成成功,proall的状态才会变成成功,此时p1、p2、p3的返回值组成一个数组,传递给proall的回调函数。(2)只要p1、p2、p3之中有一个被rejected,proall的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给proall的回调函数。// Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例// Promise.race 只有有一个promise实例的状态确定了,那真个race的状态就确定了// 多个实例,谁先加载出来,就执行谁。</code></pre><h2 id="综合案例"><a href="#综合案例" class="headerlink" title="综合案例"></a>综合案例</h2><p>要求:</p><ul><li><p>封装原生ajax请求,调用接口数据,具体实现本章节开头时的回调地狱的效果。</p></li><li><p>基于Promise封装ajax请求,调用接口数据,对比体现Promise管理异步状态的优势,功能的强大,一定要掌握promise的用法</p></li></ul><h1 id="async-amp-await"><a href="#async-amp-await" class="headerlink" title="async & await"></a>async & await</h1><h2 id="基本用法-6"><a href="#基本用法-6" class="headerlink" title="基本用法"></a>基本用法</h2><p>ES2017 标准引入了 async 函数,使得异步操作变得更加方便。</p><p>async 函数是什么?</p><ul><li>async 关键字,用来修饰函数,把这种函数称之为asyn函数</li><li>async 是es8中,引入的,一个用于异步编程的一种解决方案;</li><li>async函数返回一个 Promise 对象,可以使用then方法添加回调函数。</li><li><code>async</code>函数内部<code>return</code>语句返回的值,会成为<code>then</code>方法回调函数的参数</li></ul><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//undefined</span><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//Promise PromiseState:'fulfilled' PromiseResult:undefined</span><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//Promise PromiseState:'fulfilled' PromiseResult:0</span> <span class="token comment">//async函数返回一个 Promise 对象,可以使用then方法添加回调函数。</span><span class="token function">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token operator">=></span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//0</span></code></pre><h2 id="await"><a href="#await" class="headerlink" title="await"></a>await</h2><ul><li>await命令与async配合使用,正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。</li></ul><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">f2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">let</span> res <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span>reject</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token punctuation">{</span>msg<span class="token operator">:</span><span class="token string">'嘿嘿嘿'</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token keyword">else</span><span class="token punctuation">{</span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token punctuation">{</span>msg<span class="token operator">:</span><span class="token string">'error~'</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">f2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">f3</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">let</span> res <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token number">123</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> res<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">f3</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">f3</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><ul><li>当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。</li><li>await 不是同步的,是异步的,遇到await以后,await后的代码会进入任务队列,当所有的主线程上的同步任务执行完以后,才会执行await;</li></ul><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">f4</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">111111</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> r <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token number">22222</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>r<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">33333</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">f4</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">444444</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><ul><li>await 命令必须写在async函数中,否则语法错误</li></ul><h2 id="async-函数有多种使用形式。"><a href="#async-函数有多种使用形式。" class="headerlink" title="async 函数有多种使用形式。"></a>async 函数有多种使用形式。</h2><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 函数声明</span><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token comment">// 函数表达式</span><span class="token keyword">const</span> <span class="token function-variable function">foo</span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">// 对象的方法</span><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function-variable function">fn</span><span class="token operator">:</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token keyword">async</span> <span class="token function">demo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token keyword">async</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>obj<span class="token punctuation">.</span><span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token operator">...</span><span class="token punctuation">)</span><span class="token comment">// Class 的方法</span><span class="token keyword">class</span> <span class="token class-name">Storage</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>cachePromise <span class="token operator">=</span> caches<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token string">'avatars'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">async</span> <span class="token function">getAvatar</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> cache <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token keyword">this</span><span class="token punctuation">.</span>cachePromise<span class="token punctuation">;</span> <span class="token keyword">return</span> cache<span class="token punctuation">.</span><span class="token function">match</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/avatars/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.jpg</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token keyword">const</span> storage <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Storage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>storage<span class="token punctuation">.</span><span class="token function">getAvatar</span><span class="token punctuation">(</span><span class="token string">'jake'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>…<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 箭头函数</span><span class="token keyword">const</span> <span class="token function-variable function">foo</span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre><h2 id="案例对比"><a href="#案例对比" class="headerlink" title="案例对比"></a>案例对比</h2><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">//结合上一章节回调地狱,promise,对比async处理异步操作</span><span class="token number">1.</span>原生ajax回调地狱<span class="token function">request_ajax</span><span class="token punctuation">(</span><span class="token string">'GET'</span><span class="token punctuation">,</span> <span class="token string">'http://localhost:4000?name=三体'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token punctuation">{</span>data<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span>author<span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">}</span> <span class="token operator">=</span> res<span class="token punctuation">;</span> <span class="token function">request_ajax</span><span class="token punctuation">(</span><span class="token string">'GET'</span><span class="token punctuation">,</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">http://localhost:4000?author=</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>author<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">re</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>re<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token number">2.</span>promise形式<span class="token function">request_ajax_promise</span><span class="token punctuation">(</span><span class="token string">'get'</span><span class="token punctuation">,</span> <span class="token string">'http://localhost:4000?name=三体'</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token punctuation">{</span> data<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span>author<span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">}</span> <span class="token operator">=</span> res<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token function">request_ajax_promise</span><span class="token punctuation">(</span><span class="token string">'get'</span><span class="token punctuation">,</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">http://localhost:4000?author=</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>author<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token number">3.</span>async形式<span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">getdata</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">let</span> res <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">request_ajax_promise</span><span class="token punctuation">(</span><span class="token string">'get'</span><span class="token punctuation">,</span> <span class="token string">'http://localhost:4000?name=三体'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token punctuation">{</span> data<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span>name<span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">}</span> <span class="token operator">=</span> res<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">await</span> <span class="token function">request_ajax_promise</span><span class="token punctuation">(</span><span class="token string">'get'</span><span class="token punctuation">,</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">http://localhost:4000?name=</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">getdata</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token operator">=></span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h2 id="Fetch-API"><a href="#Fetch-API" class="headerlink" title="Fetch API"></a><a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch">Fetch API</a></h2><ul><li>fetch 基于promise</li><li>默认是get 方式</li><li>提供了一个全局 fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。 这种功能以前是使用 XMLHttpRequest 实现的。Fetch 提供了一个更理想的替代方案</li></ul><pre class="language-js" data-language="js"><code class="language-js"><span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">'http://localhost:4000?name=三体'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token operator">=></span><span class="token punctuation">{</span> <span class="token comment">// 返回的是服务端的响应。不是真正的数据;</span> <span class="token comment">// 但是,我们要获取数据,就要 使用一个方法res.json();</span> <span class="token comment">// console.log(res);</span> <span class="token keyword">return</span> res<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token operator">=></span><span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token punctuation">{</span> data<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span>author<span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">}</span> <span class="token operator">=</span> res<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">http://localhost:4000?author=</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>author<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token operator">=></span><span class="token punctuation">{</span> <span class="token keyword">return</span> res<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token operator">=></span><span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//fetch 与 async 结合使用demo</span><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> res <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">'http://localhost:4000?name=三体'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> res <span class="token operator">=</span> <span class="token keyword">await</span> res<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token punctuation">{</span>data<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span>author<span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">}</span> <span class="token operator">=</span> res<span class="token punctuation">;</span> <span class="token keyword">let</span> r <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">http://localhost:4000?author=</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>author<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">await</span> r<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">res</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p><a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch">参阅文档讲解学习</a></p><h1 id="class-amp-module"><a href="#class-amp-module" class="headerlink" title="class & module"></a>class & module</h1><h2 id="Class"><a href="#Class" class="headerlink" title="Class"></a>Class</h2><h3 id="类的由来"><a href="#类的由来" class="headerlink" title="类的由来"></a>类的由来</h3><p>ES6之前,JavaScript 语言中,生成实例对象的传统方法是通过构造函数。下面是一个例子。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">Stu</span><span class="token punctuation">(</span><span class="token parameter">n<span class="token punctuation">,</span>a</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> n<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> a<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token class-name">Stu</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">say</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">let</span> stu1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Stu</span><span class="token punctuation">(</span><span class="token string">'lisi'</span><span class="token punctuation">,</span><span class="token number">12</span><span class="token punctuation">)</span><span class="token punctuation">;</span>stu1<span class="token punctuation">.</span><span class="token function">say</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>这种写法跟传统的面向对象语言(比如 C++ 和 Java)差异很大,很容易让新学习这门语言的程序员感到困惑。</p><pre class="language-java" data-language="java"><code class="language-java"><span class="token comment">//java面向对象封装</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Demo02Method</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">int</span><span class="token punctuation">[</span><span class="token punctuation">]</span> array <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">15</span><span class="token punctuation">,</span><span class="token number">25</span><span class="token punctuation">,</span><span class="token number">35</span><span class="token punctuation">,</span><span class="token number">111</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">int</span> max <span class="token operator">=</span> <span class="token function">getMax</span><span class="token punctuation">(</span>array<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>max<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">int</span> <span class="token function">getMax</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">[</span><span class="token punctuation">]</span> array<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">int</span> max <span class="token operator">=</span> array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> array<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>array<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">></span> max<span class="token punctuation">)</span> <span class="token punctuation">{</span> max <span class="token operator">=</span> array<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> max<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><h3 id="ES6类的定义"><a href="#ES6类的定义" class="headerlink" title="ES6类的定义"></a>ES6类的定义</h3><p>ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过<code>class</code>关键字,可以定义类。新的<code>class</code>写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。</p><p>ES6中,使用class 来定义类,用来生成实例对象。ES6 的类,完全可以看作构造函数的另一种写法。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">class</span> 类名<span class="token punctuation">{</span> <span class="token comment">//默认会存在一个构造器constructor</span> <span class="token comment">//constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。</span> <span class="token comment">//一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。</span> <span class="token comment">//class 中的constructor方法,就是构造方法</span><span class="token punctuation">}</span><span class="token keyword">class</span> <span class="token class-name">Point</span><span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">n<span class="token punctuation">,</span>a</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> n<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> a<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment">//在class中定义的方法,都是挂在在原型对像上的,所有的实例都可以共享。</span><span class="token comment">//定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了。</span><span class="token comment">//另外,方法之间不需要逗号分隔,加了会报错</span><span class="token keyword">class</span> <span class="token class-name">Point</span><span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">n<span class="token punctuation">,</span>a</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> n<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> a<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">say</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><p>使用的时候,也是直接对类使用<code>new</code>命令,跟构造函数的用法完全一致。如果忘记加上<code>new</code>,像函数那样调用<code>Class</code>,将会报错。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> stu1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Stu</span><span class="token punctuation">(</span><span class="token string">'lisi'</span><span class="token punctuation">,</span><span class="token number">34</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>stu1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Stu {name: "liis", age: 34}</span><span class="token keyword">let</span> stu1 <span class="token operator">=</span> <span class="token function">Stu</span><span class="token punctuation">(</span><span class="token string">'lisi'</span><span class="token punctuation">,</span><span class="token number">34</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//err</span></code></pre><p>类的所有方法都定义在类的<code>prototype</code>属性上面。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Stu</span><span class="token punctuation">{</span> <span class="token function">say</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">hello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment">//等同于</span><span class="token class-name">Stu</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">say</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token class-name">Stu</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">hello</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token comment">//在类的实例上面调用方法,其实就是调用原型上的方法。</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>stu1<span class="token punctuation">.</span>say <span class="token operator">===</span> <span class="token class-name">Stu</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>say<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h3 id="取值函数(getter)和存值函数(setter)"><a href="#取值函数(getter)和存值函数(setter)" class="headerlink" title="取值函数(getter)和存值函数(setter)"></a>取值函数(getter)和存值函数(setter)</h3><p>在“类”的内部可以使用<code>get</code>和<code>set</code>关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">MyClass</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ...</span> <span class="token punctuation">}</span> <span class="token keyword">get</span> <span class="token function">prop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">'getter'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">set</span> <span class="token function">prop</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'setter: '</span><span class="token operator">+</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token keyword">let</span> inst <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">MyClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>inst<span class="token punctuation">.</span>prop <span class="token operator">=</span> <span class="token number">123</span><span class="token punctuation">;</span><span class="token comment">// setter: 123</span>inst<span class="token punctuation">.</span>prop<span class="token comment">// 'getter'</span></code></pre><h3 id="静态方法"><a href="#静态方法" class="headerlink" title="静态方法"></a>静态方法</h3><p>所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上<code>static</code>关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Foo</span> <span class="token punctuation">{</span> <span class="token keyword">static</span> <span class="token function">classMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 静态方法中的this,并不指向实例对象;// 此处,this指向class 本身</span> <span class="token keyword">return</span> <span class="token string">'hello'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span>Foo<span class="token punctuation">.</span><span class="token function">classMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// 'hello'</span><span class="token keyword">var</span> foo <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>foo<span class="token punctuation">.</span><span class="token function">classMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre><h3 id="静态属性"><a href="#静态属性" class="headerlink" title="静态属性"></a>静态属性</h3><p>静态属性指的是 Class 本身的属性,即<code>Class.propName</code>,而不是定义在实例对象(<code>this</code>)上的属性。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">class</span> <span class="token class-name">Foo</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>Foo<span class="token punctuation">.</span>prop <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>Foo<span class="token punctuation">.</span>prop <span class="token comment">// 1</span></code></pre><p>上面的写法为<code>Foo</code>类定义了一个静态属性<code>prop</code>。</p><p>目前,只有这种写法可行,因为 ES6 明确规定,Class 内部只有静态方法,没有静态属性。现在有一个<a href="https://github.com/tc39/proposal-class-fields">提案</a>提供了类的静态属性,写法是在实例属性的前面,加上<code>static</code>关键字。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">class</span> <span class="token class-name">MyClass</span> <span class="token punctuation">{</span> <span class="token keyword">static</span> myStaticProp <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>MyClass<span class="token punctuation">.</span>myStaticProp<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 42</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><h2 id="Class-的继承"><a href="#Class-的继承" class="headerlink" title="Class 的继承"></a>Class 的继承</h2><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">//回顾:构造函数继承</span><span class="token keyword">function</span> <span class="token function">Ani</span><span class="token punctuation">(</span><span class="token parameter">f</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>foot <span class="token operator">=</span> f<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>type <span class="token operator">=</span> <span class="token string">'猫科动物'</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">tiger</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token function">Ani</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">'cookie'</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">let</span> t1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">tiger</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>t1<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>Class 可以通过结合extends关键字和 super()方法实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">//父类</span><span class="token keyword">class</span> <span class="token class-name">Ani</span><span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">f</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>foot <span class="token operator">=</span> f<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>type <span class="token operator">=</span> <span class="token string">'猫科动物'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment">//子类</span><span class="token keyword">class</span> <span class="token class-name">tiger</span> <span class="token keyword">extends</span> <span class="token class-name">Ani</span><span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">// 子类必须在constructor方法中调用super方法,否则新建实例时会报错。</span> <span class="token comment">// 这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,</span> <span class="token comment">// 得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。</span> <span class="token comment">// 如果不调用super方法,子类就得不到this对象。</span> <span class="token keyword">super</span><span class="token punctuation">(</span><span class="token number">40</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">'cookie'</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token keyword">let</span> t1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">tiger</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>t1<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h2 id="Module"><a href="#Module" class="headerlink" title="Module"></a>Module</h2><h3 id="概述-1"><a href="#概述-1" class="headerlink" title="概述"></a>概述</h3><p>历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。其他语言都有这项功能,比如 Ruby 的<code>require</code>、Python 的<code>import</code>,甚至就连 CSS 都有<code>@import</code>,但是 JavaScript 任何这方面的支持都没有,这对开发大型的、复杂的项目形成了巨大障碍。</p><p>在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。</p><p>ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。</p><pre class="language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// CommonJS模块</span><span class="token keyword">let</span> <span class="token punctuation">{</span> stat<span class="token punctuation">,</span> exists<span class="token punctuation">,</span> readfile <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'fs'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 等同于</span><span class="token keyword">let</span> _fs <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'fs'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> stat <span class="token operator">=</span> _fs<span class="token punctuation">.</span>stat<span class="token punctuation">;</span><span class="token keyword">let</span> exists <span class="token operator">=</span> _fs<span class="token punctuation">.</span>exists<span class="token punctuation">;</span><span class="token keyword">let</span> readfile <span class="token operator">=</span> _fs<span class="token punctuation">.</span>readfile<span class="token punctuation">;</span>上面代码的实质是整体加载fs模块(即加载fs的所有方法),生成一个对象(_fs),然后再从这个对象上面读取 <span class="token number">3</span> 个方法。这种加载称为“运行时加载”,因为只有运行时才能得到这个对象,导致完全没办法在编译时做“静态优化”。</code></pre><p>ES6 模块不是对象,而是通过<code>export</code>命令显式指定输出的代码,再通过<code>import</code>命令输入。</p><h3 id="export"><a href="#export" class="headerlink" title="export"></a>export</h3><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">// 文件 one.js 通过export命令指定输出代码</span><span class="token comment">// 1.</span><span class="token keyword">export</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span><span class="token keyword">export</span> <span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span><span class="token string">"方腊"</span><span class="token punctuation">}</span><span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">'export function fn'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token comment">//ES6 将其视为一个模块,里面用export命令对外部输出了三个变量。</span><span class="token comment">//2.</span><span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span><span class="token keyword">let</span> userinfo <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span><span class="token string">'jq'</span><span class="token punctuation">}</span><span class="token keyword">class</span> <span class="token class-name">Ani</span><span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>type <span class="token operator">=</span> <span class="token string">'犬'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token keyword">export</span> <span class="token punctuation">{</span>a<span class="token punctuation">,</span>userinfo<span class="token punctuation">,</span>Ani<span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">//上面代码在export命令后面,使用大括号指定所要输出的一组变量。它与前一种写法(直接放置在var语句前)是等价的,但是应该优先考虑使用这种写法。因为这样就可以在脚本尾部,一眼看清楚输出了哪些变量。</span><span class="token comment">//通常情况下,export输出的变量就是本来的名字,但是可以使用as关键字重命名。</span><span class="token keyword">export</span> <span class="token punctuation">{</span>a<span class="token punctuation">,</span>userinfo <span class="token keyword">as</span> u<span class="token punctuation">,</span>Ani<span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">//注意:export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。</span><span class="token comment">// 报错</span><span class="token keyword">export</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token comment">// 报错</span><span class="token keyword">var</span> m <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">export</span> m<span class="token punctuation">;</span><span class="token comment">// 正确写法一 </span><span class="token keyword">export</span> <span class="token keyword">var</span> m <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token comment">// 正确写法二</span><span class="token keyword">var</span> m <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">export</span> <span class="token punctuation">{</span>m<span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">// 正确写法三</span><span class="token keyword">var</span> n <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">export</span> <span class="token punctuation">{</span>n <span class="token keyword">as</span> m<span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre><h3 id="import-命令"><a href="#import-命令" class="headerlink" title="import 命令"></a>import 命令</h3><pre class="language-js" data-language="js"><code class="language-js">文件 two<span class="token punctuation">.</span>js<span class="token comment">//使用export命令定义了模块的对外接口以后,其他 JS 文件就可以通过import命令加载这个模块。</span><span class="token keyword">import</span> <span class="token punctuation">{</span>a<span class="token punctuation">,</span>obj<span class="token punctuation">,</span>fn<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'one.js'</span><span class="token punctuation">;</span><span class="token comment">//从模块one.js中,输入变量, import必须接受一个大括号,里面指定从其他模块导入的变量名,大括号里的变量名,必须与被导入的模块,对外暴露的接口名称相同。</span><span class="token comment">//如果想为输入的变量重新取一个名字,import命令要使用as关键字,将输入的变量重命名。</span><span class="token keyword">import</span> <span class="token punctuation">{</span> a<span class="token punctuation">,</span> obj <span class="token keyword">as</span> person<span class="token punctuation">,</span>fn<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'one.js'</span><span class="token comment">//import命令输入的变量都是只读的,因为它的本质是输入接口。不允许在加载模块的脚本里面,改写接口。但是,如果a是一个对象,改写a的属性是允许的。</span></code></pre><h3 id="export-default-命令"><a href="#export-default-命令" class="headerlink" title="export default 命令"></a>export default 命令</h3><p>使用<code>import</code>命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法。</p><p>为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到<code>export default</code>命令,为模块指定默认输出。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">// ./export-default</span><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'foo'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">//默认输出是一个函数。</span><span class="token comment">//其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。</span><span class="token keyword">import</span> customName <span class="token keyword">from</span> <span class="token string">'./export-default'</span><span class="token punctuation">;</span><span class="token function">customName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 'foo'</span><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> num<span class="token operator">:</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token function">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token keyword">import</span> demo <span class="token keyword">from</span> <span class="token string">'./export-default'</span><span class="token punctuation">;</span>demo<span class="token punctuation">.</span>num <span class="token comment">//10</span></code></pre><h3 id="Module-的加载实现"><a href="#Module-的加载实现" class="headerlink" title="Module 的加载实现"></a>Module 的加载实现</h3><h4 id="1-浏览器加载"><a href="#1-浏览器加载" class="headerlink" title="1.浏览器加载"></a>1.浏览器加载</h4><p>浏览器加载 ES6 模块,也使用<code><script></code>标签,但是要加入<code>type="module"</code>属性。</p><pre class="language-js" data-language="js"><code class="language-js"><span class="token operator"><</span>script type<span class="token operator">=</span><span class="token string">"module"</span> src<span class="token operator">=</span><span class="token string">"./foo.js"</span><span class="token operator">></span><span class="token operator"><</span><span class="token operator">/</span>script<span class="token operator">></span> 由于type属性设为module,所以浏览器知道这是一个 <span class="token constant">ES6</span> 模块。</code></pre><h4 id="2-Node-js-的模块加载方法"><a href="#2-Node-js-的模块加载方法" class="headerlink" title="2.Node.js 的模块加载方法"></a>2.Node.js 的模块加载方法</h4><p>JavaScript 现在有两种模块。一种是 ES6 模块,简称 ESM;另一种是 CommonJS 模块,简称 CJS。</p><p>CommonJS 模块是 Node.js 专用的,与 ES6 模块不兼容。语法上面,两者最明显的差异是,CommonJS 模块使用<code>require()</code>和<code>module.exports</code>,ES6 模块使用<code>import</code>和<code>export</code>。</p><p>它们采用不同的加载方案。从 Node.js v13.2 版本开始,Node.js 已经默认打开了 ES6 模块支持。</p><p>Node.js 要求 ES6 模块采用<code>.mjs</code>后缀文件名。也就是说,只要脚本文件里面使用<code>import</code>或者<code>export</code>命令,那么就必须采用<code>.mjs</code>后缀名。Node.js 遇到<code>.mjs</code>文件,就认为它是 ES6 模块</p>]]></content>
<categories>
<category> JS </category>
</categories>
<tags>
<tag> es6 </tag>
</tags>
</entry>
</search>