-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
317 lines (152 loc) · 369 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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>readme</title>
<link href="/2023/10/10/readme/"/>
<url>/2023/10/10/readme/</url>
<content type="html"><![CDATA[<p>this is the test demo.</p>]]></content>
</entry>
<entry>
<title>JavaScript笔记初阶</title>
<link href="/2022/03/22/JavaScript%E7%AC%94%E8%AE%B0%E5%88%9D%E9%98%B6/"/>
<url>/2022/03/22/JavaScript%E7%AC%94%E8%AE%B0%E5%88%9D%E9%98%B6/</url>
<content type="html"><![CDATA[<h1 id="JavaScript"><a href="#JavaScript" class="headerlink" title="JavaScript"></a>JavaScript</h1><p>JavaScript负责页面中的的行为。</p><p>它是一门运行在浏览器端的脚本语言。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span>></span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"> <span class="title function_">alert</span>(<span class="string">"Hello World! 111"</span>); <span class="comment">//弹出窗口不关闭,后续不会执行</span></span></span><br><span class="line"><span class="language-javascript"> <span class="variable language_">document</span>.<span class="title function_">write</span>(<span class="string">"Hello World! 222"</span>); <span class="comment">//输出在body中,不会在script中输出</span></span></span><br><span class="line"><span class="language-javascript"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"Hello World! 333"</span>); <span class="comment">//输出在控制台</span></span></span><br><span class="line"><span class="language-javascript"></span><span class="tag"></<span class="name">script</span>></span></span><br></pre></td></tr></table></figure><h2 id="JS的编写的位置"><a href="#JS的编写的位置" class="headerlink" title="JS的编写的位置"></a>JS的编写的位置</h2><p>1.可以编写到标签的指定属性中</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">button</span> <span class="attr">onclick</span>=<span class="string">"alert('hello');"</span>></span>我是按钮<span class="tag"></<span class="name">button</span>></span> </span><br><span class="line">// 切记这里面文本内容用单引号括起来,不能用双引号!!</span><br><span class="line"><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"javascript:alert('clickherehhh');"</span>></span>超链接<span class="tag"></<span class="name">a</span>></span> </span><br></pre></td></tr></table></figure><p>2.可以编写到script标签中</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span>></span><span class="language-javascript"> </span></span><br><span class="line"><span class="language-javascript"><span class="comment">//编写js代码 </span></span></span><br><span class="line"><span class="language-javascript"></span><span class="tag"></<span class="name">script</span>></span> </span><br></pre></td></tr></table></figure><p>3.可以将代码编写到外部的js文件中,然后通过标签将其引入</p><p>script标签一旦用于引入外部文件了,就不能在编写代码了,即使编写了浏览器也会忽略 ,如果需要则可以在创建一个新的script标签用于编写内部代码</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span> <span class="attr">src</span>=<span class="string">"文件路径"</span>></span><span class="tag"></<span class="name">script</span>></span> </span><br></pre></td></tr></table></figure><h2 id="输出语句"><a href="#输出语句" class="headerlink" title="输出语句"></a>输出语句</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">alert</span>(<span class="string">"要输出的内容"</span>); <span class="comment">//弹出窗口不关闭,后续不会执行</span></span><br></pre></td></tr></table></figure><p>该语句会在浏览器窗口中弹出一个警告框</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">document</span>.<span class="title function_">write</span>(<span class="string">"要输出的内容"</span>); </span><br></pre></td></tr></table></figure><p>该内容将会被写到body标签中,并在页面中显示</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"要输出的内容"</span>); </span><br></pre></td></tr></table></figure><p>该内容会被写到开发者工具的控制台中</p><h2 id="基本的语法"><a href="#基本的语法" class="headerlink" title="基本的语法"></a>基本的语法</h2><p>js函数声明不需要;分号,但是赋值语句要加;分号</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">functionName</span>(<span class="params">arg0,arg1,arg2</span>){ </span><br><span class="line"><span class="comment">//函数声明 </span></span><br><span class="line">} </span><br><span class="line"><span class="keyword">var</span> functionName=<span class="keyword">function</span>(<span class="params">arg0,arg1,arg2</span>){ </span><br><span class="line"><span class="comment">//函数表达式 </span></span><br><span class="line">};(注意分号) </span><br></pre></td></tr></table></figure><p>注释</p><p>单行注释</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//注释内容 </span></span><br></pre></td></tr></table></figure><p>多行注释</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">注释内容 </span></span><br><span class="line"><span class="comment">*/</span> </span><br></pre></td></tr></table></figure><p>JS严格区分大小写</p><p>JS中每条语句以分号(;)结尾如果不写分号,浏览器会自动添加,但是会消耗一些系统资源, 而且有些时候,浏览器会加错分号,所以在开发中分号必须写</p><p>JS中会自动忽略多个空格和换行,所以我们可以利用空格和换行对代码进行格式化。</p><h2 id="字面量和变量"><a href="#字面量和变量" class="headerlink" title="字面量和变量"></a>字面量和变量</h2><h3 id="字面量"><a href="#字面量" class="headerlink" title="字面量"></a>字面量</h3><p>字面量实际上就是一些固定的值,比如 1 2 3 4 true false null NaN “hello”<br><strong>字面量都是不可以改变的。</strong></p><p>由于字面量不是很方便使用,所以在JS中很少直接使用字面量</p><h3 id="变量"><a href="#变量" class="headerlink" title="变量"></a>变量</h3><p>变量可以用来保存字面量,并且可以保存任意的字面量</p><p>一般都是通过变量来使用字面量,而不直接使用字面量,而且也可以通过变量来对字面量进行一个描述</p><p>声明变量</p><p>使用var关键字来声明一个变量</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a; </span><br></pre></td></tr></table></figure><p>为变量赋值</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">a = <span class="number">1</span>; </span><br></pre></td></tr></table></figure><p>声明和赋值同时进行</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="number">456</span>; </span><br></pre></td></tr></table></figure><h3 id="标识符"><a href="#标识符" class="headerlink" title="标识符"></a>标识符</h3><p>在JS中所有的可以自主命名的内容,都可以认为是一个标识符,<br>是标识符就应该遵守标识符的规范。</p><p>比如:变量名、函数名、属性名</p><p>规范:<br>1.标识符中可以含有字母、数字、_、$<br>2.标识符不能以数字开头<br>3.标识符不能是JS中的关键字和保留字<br>4.标识符一般采用驼峰命名法<br>xxxYyyZzz</p><h1 id="数据类型"><a href="#数据类型" class="headerlink" title="数据类型"></a>数据类型</h1><h2 id="六种数据类型"><a href="#六种数据类型" class="headerlink" title="六种数据类型"></a>六种数据类型</h2><p><strong>JS中一共分成六种数据类型 5个基本数据类型+object</strong></p><ul><li>String 字符串</li><li>Number 数值</li><li>Boolean 布尔值</li><li>Null 空值</li><li>Undefined 未定义</li><li>Object 对象</li></ul><p>其中基本数据类型有 5 个, Object属于引用数据类型</p><p><strong>typeof运算符检查数据类型</strong></p><h3 id="1-String-字符串"><a href="#1-String-字符串" class="headerlink" title="1.String 字符串"></a>1.String 字符串</h3><p>JS中的字符串需要使用引号引起来双引号或单引号都行<br>在字符串中使用\作为转义字符</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">\<span class="string">' ==> '</span> </span><br><span class="line">\<span class="string">" ==> "</span> </span><br><span class="line">\n ==> 换行 </span><br><span class="line">\t ==> 制表符 </span><br><span class="line">\\ ==> \ </span><br></pre></td></tr></table></figure><p>使用typeof运算符检查字符串时,会返回”string”</p><h3 id="2-Number-数值"><a href="#2-Number-数值" class="headerlink" title="2.Number 数值"></a>2.Number 数值</h3><p><strong>JS中所有的整数和浮点数都是Number类型</strong></p><p>最大能表示的值:Number.MAX_VALUE= 1.7976931348623157e+308</p><p>特殊的数字:能赋值给变量 </p><ul><li>Infinity 正无穷 a = Infinity ,能赋值 </li><li>-Infinity 负无穷 </li><li>NaN 非法数字(Not A Number)</li></ul><p>其他进制的数字的表示:<br>0b 开头表示二进制,但是不是所有的浏览器都支持<br>0 开头表示八进制<br>0x 开头表示十六进制</p><p>使用typeof检查一个Number类型的数据时,会返回”number”<br>(包括NaN 和 Infinity)</p><h3 id="3-Boolean-布尔值"><a href="#3-Boolean-布尔值" class="headerlink" title="3.Boolean 布尔值"></a>3.Boolean 布尔值</h3><p>布尔值主要用来进行逻辑判断,布尔值只有两个</p><ul><li><p>true 逻辑的真</p></li><li><p>false 逻辑的假</p></li></ul><p>使用typeof检查一个布尔值时,会返回”boolean”</p><h3 id="4-Null-空值"><a href="#4-Null-空值" class="headerlink" title="4.Null 空值"></a>4.Null 空值</h3><p>空值专门用来表示为空的对象,Null类型的值只有一个 <strong>null</strong></p><p>使用typeof检查一个Null类型的值时会返回”object”</p><h3 id="5-Undefined-未定义"><a href="#5-Undefined-未定义" class="headerlink" title="5.Undefined 未定义"></a>5.Undefined 未定义</h3><p><strong>如果声明一个变量但是没有为变量赋值此时变量的值就是undefined</strong></p><p>该类型的值只有一个 undefined</p><p>使用typeof检查一个Undefined类型的值时,会返回”undefined”</p><h3 id="引用数据类型"><a href="#引用数据类型" class="headerlink" title="引用数据类型"></a>引用数据类型</h3><p>Object 对象</p><h2 id="类型转换"><a href="#类型转换" class="headerlink" title="类型转换"></a>类型转换</h2><p>类型转换就是指将其他的数据类型,转换为String Number 或 Boolean</p><h3 id="转换为String"><a href="#转换为String" class="headerlink" title="转换为String"></a>转换为String</h3><h4 id="方式一(强制类型转换):"><a href="#方式一(强制类型转换):" class="headerlink" title="方式一(强制类型转换):"></a>方式一(强制类型转换):</h4><p><strong>调用被转换数据的toString()方法</strong><br>例子:<br> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="number">123</span>; </span><br><span class="line">a = a.<span class="title function_">toString</span>(); </span><br></pre></td></tr></table></figure></p><p>注意:<strong>这个方法不适用于 null 和 undefined</strong><br>由于这两个类型的数据中没有方法,所以调用toString()时会报错</p><h4 id="方式二(强制类型转换):"><a href="#方式二(强制类型转换):" class="headerlink" title="方式二(强制类型转换):"></a>方式二(强制类型转换):</h4><p><strong>调用String()函数</strong><br>例子:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="number">123</span>; </span><br><span class="line">a = <span class="title class_">String</span>(a); </span><br></pre></td></tr></table></figure><p>原理:<strong>对于Number Boolean String都会调用他们的toString()方法来将其转换为字符串,对于null值,直接转换为字符串”null”。对于undefined直接转换为字符串”undefined”</strong></p><h4 id="方式三(隐式的类型转换)"><a href="#方式三(隐式的类型转换)" class="headerlink" title="方式三(隐式的类型转换):"></a>方式三(隐式的类型转换):</h4><p><strong>为任意的数据类型 +””</strong><br>例子:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="literal">true</span>; </span><br><span class="line">a = a + <span class="string">""</span>; </span><br></pre></td></tr></table></figure><p>原理:和String()函数一样</p><h3 id="转换为Number"><a href="#转换为Number" class="headerlink" title="转换为Number"></a>转换为Number</h3><h4 id="方式一(强制类型转换):-1"><a href="#方式一(强制类型转换):-1" class="headerlink" title="方式一(强制类型转换):"></a>方式一(强制类型转换):</h4><p><strong>调用Number()函数</strong><br>例子:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> s = <span class="string">"123"</span>; </span><br><span class="line">s = <span class="title class_">Number</span>(s); </span><br></pre></td></tr></table></figure><p>转换的情况:</p><ol><li>字符串 > 数字<br>如果字符串是一个合法的数字,则直接转换为对应的数字<br>如果字符串是一个非法的数字,则转换为NaN<br>如果是一个空串或纯空格的字符串,则转换为0</li><li>布尔值 > 数字<br>true转换为1<br>false转换为0</li><li>空值 > 数字<br>null转换为0</li><li>未定义 > 数字<br>undefined 转换为NaN</li></ol><h4 id="方式二(强制类型转换):-1"><a href="#方式二(强制类型转换):-1" class="headerlink" title="方式二(强制类型转换):"></a>方式二(强制类型转换):</h4><p>调用parseInt()或parseFloat()<br>这两个函数专门用来将一个字符串转换为数字的</p><p>如果对非String使用parseInt()或parseFloat(),它会<strong>先将其转换为String</strong>然后在操作 parseInt()<br>可以将<strong>一个字符串中的有效的整数位</strong>提取出来,并转换为Number<br>例子:<br> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="string">"123.456px"</span>; </span><br><span class="line">a = <span class="built_in">parseInt</span>(a); <span class="comment">//123 </span></span><br></pre></td></tr></table></figure><br>如果需要可以在parseInt()中指定一个第二个参数,来指定进制parseFloat()可以将一个<strong>字符串中的有效的小数位</strong>提取出来,并转换为Number<br>例子:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="string">"123.456px"</span>; </span><br><span class="line">a = <span class="built_in">parseFloat</span>(a); <span class="comment">//123.456 </span></span><br></pre></td></tr></table></figure><h4 id="方式三(隐式的类型转换):"><a href="#方式三(隐式的类型转换):" class="headerlink" title="方式三(隐式的类型转换):"></a>方式三(隐式的类型转换):</h4><p>使用一元的+来进行隐式的类型转换<br>例子:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="string">"123"</span>; </span><br><span class="line">a = +a; </span><br></pre></td></tr></table></figure><p><strong>原理:和Number()函数一样</strong></p><h3 id="转换为布尔值"><a href="#转换为布尔值" class="headerlink" title="转换为布尔值"></a>转换为布尔值</h3><h4 id="方式一(强制类型转换):-2"><a href="#方式一(强制类型转换):-2" class="headerlink" title="方式一(强制类型转换):"></a>方式一(强制类型转换):</h4><p>使用Boolean()函数<br>例子:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> s = <span class="string">"false"</span>; </span><br><span class="line">s = <span class="title class_">Boolean</span>(s); <span class="comment">//true </span></span><br></pre></td></tr></table></figure><p>转换的情况<br>字符串 > 布尔<br>除了空串其余全是true</p><p>数值 > 布尔<br>除了0和NaN其余的全是true</p><p>null、undefined > 布尔<br>都是false</p><p>对象 > 布尔<br>都是true</p><h4 id="方式二(隐式类型转换):"><a href="#方式二(隐式类型转换):" class="headerlink" title="方式二(隐式类型转换):"></a>方式二(隐式类型转换):</h4><p><strong>为任意的数据类型做两次非运算,即可将其转换为布尔值</strong><br>例子:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="string">"hello"</span>; </span><br><span class="line">a = !!a; <span class="comment">//true </span></span><br></pre></td></tr></table></figure><h1 id="基础语法"><a href="#基础语法" class="headerlink" title="基础语法"></a>基础语法</h1><h2 id="运算符"><a href="#运算符" class="headerlink" title="运算符"></a>运算符</h2><p>运算符也称为操作符<br>通过运算符可以对一个或多个值进行运算或操作</p><h3 id="typeof运算符"><a href="#typeof运算符" class="headerlink" title="typeof运算符"></a>typeof运算符</h3><p>用来检查一个变量的数据类型<br>语法:typeof 变量<br>它会返回一个用于描述类型的字符串作为结果</p><h3 id="算数运算符"><a href="#算数运算符" class="headerlink" title="算数运算符"></a>算数运算符</h3><p>+&ensp;对两个值进行加法运算并返回结果<br>-&ensp;对两个值进行减法运算并返回结果<br>*&ensp;对两个值进行乘法运算并返回结果<br>/&ensp;对两个值进行除法运算并返回结果<br>%&ensp;对两个值进行取余运算并返回结果</p><p><strong>除了加法以外,对非Number类型的值进行运算时,都会先转换为Number然后在做运算。</strong><br>而做加法运算时,如果是两个字符串进行相加,则会做拼串操作,将两个字符连接为一个字符串。<br>任何值和字符串做加法,都会先转换为字符串,然后再拼串</p><h3 id="一元运算符"><a href="#一元运算符" class="headerlink" title="一元运算符"></a>一元运算符</h3><p>一元运算符只需要一个操作数</p><h4 id="一元的"><a href="#一元的" class="headerlink" title="一元的+"></a>一元的+</h4><p>就是正号,不会对值产生任何影响,但是可以将一个非数字转换为数字<br>例子:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="literal">true</span>; </span><br><span class="line">a = +a; </span><br></pre></td></tr></table></figure><h4 id="一元的-1"><a href="#一元的-1" class="headerlink" title="一元的-"></a>一元的-</h4><p>就是负号,可以对一个数字进行符号位取反<br>例子:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="number">10</span>; </span><br><span class="line">a = a; </span><br></pre></td></tr></table></figure><h4 id="自增"><a href="#自增" class="headerlink" title="自增"></a>自增</h4><p>自增可以使变量在原值的基础上自增1<br>自增使用 ++<br>自增可以使用 前++(++a)后++(a++)<br>无论是++a 还是 a++都会立即使原变量自增1<br>不同的是++a和a++的值是不同的,<br>++a的值是变量的新值(自增后的值)<br>a++的值是变量的原值(自增前的值)</p><h4 id="自减"><a href="#自减" class="headerlink" title="自减"></a>自减</h4><p>自减可以使变量在原值的基础上自减1<br>自减使用<br>自减可以使用 前(a)后(a)<br>无论是a 还是 a都会立即使原变量自减1<br>不同的是a和a的值是不同的,<br>a的值是变量的新值(自减后的值)<br>a的值是变量的原值(自减前的值)</p><h3 id="逻辑运算符"><a href="#逻辑运算符" class="headerlink" title="逻辑运算符"></a>逻辑运算符</h3><ol><li><p>!<br>非运算可以对一个布尔值进行取反,true变false false边true<br>当对非布尔值使用!时,会先将其转换为布尔值然后再取反<br>我们可以利用!来将其他的数据类型转换为布尔值</p></li><li><p>&&<br>&&可以对符号两侧的值进行与运算<br>只有两端的值都为true时,才会返回true。只要有一个false就会返回false。<br>与是一个短路的与,如果第一个值是false,则不再检查第二个值<br>对于非布尔值,它会将其转换为布尔值然后做运算,并返回原值</p></li></ol><blockquote><p><strong>规则:</strong><br>1.如果第一个值为false,则返回第一个值<br>2.如果第一个值为true,则返回第二个值</p></blockquote><ol start="3"><li>||<br>||可以对符号两侧的值进行或运算<br>只有两端都是false时,才会返回false。只要有一个true,就会返回true。<br>或是一个短路的或,如果第一个值是true,则不再检查第二个值<br>对于非布尔值,它会将其转换为布尔值然后做运算,并返回原值</li></ol><blockquote><p><strong>规则:</strong><br>1.如果第一个值为true,则返回第一个值<br>2.如果第一个值为false,则返回第二个值</p></blockquote><h3 id="赋值运算符"><a href="#赋值运算符" class="headerlink" title="赋值运算符"></a>赋值运算符</h3><ol><li><p>等于号 =<br>可以将符号右侧的值赋值给左侧变量 </p></li><li><p>加等 +=</p></li></ol><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">a += 5; //相当于 a = a + 5 </span><br><span class="line">var str = "hello"; </span><br><span class="line">str += "world"; </span><br></pre></td></tr></table></figure><ol start="3"><li>减等 -=</li></ol><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">a -= 5; //相当于 a = a-5 </span><br></pre></td></tr></table></figure><ol start="4"><li>乘等 *=</li></ol><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">a *= 5; //相当于 a = a*5 </span><br></pre></td></tr></table></figure><ol start="5"><li>除等 /=</li></ol><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">a /= <span class="number">5</span> 相当于 a = a/<span class="number">5</span> </span><br></pre></td></tr></table></figure><ol start="6"><li>取余等 %=</li></ol><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">a %= <span class="number">5</span> 相当于 a = a%<span class="number">5</span> </span><br></pre></td></tr></table></figure><h3 id="关系运算符"><a href="#关系运算符" class="headerlink" title="关系运算符"></a>关系运算符</h3><p>关系运算符用来比较两个值之间的大小关系的 </p><blockquote><p>=<br><<br><=<br>关系运算符的规则和数学中一致,用来比较两个值之间的关系,<br>如果关系成立则返回true,关系不成立则返回false。<br>如果比较的两个值是非数值,会将其转换为Number然后再比较。<br>如果比较的两个值都是字符串,此时会比较字符串的Unicode编码,而不会转换为Number。</p></blockquote><h3 id="相等运算符"><a href="#相等运算符" class="headerlink" title="相等运算符"></a>相等运算符</h3><p>相等,判断左右两个值是否相等,如果相等返回true,如果不等返回false<br>相等会自动对两个值进行类型转换,如果<strong>对不同的类型进行比较,会将其转换为相同的类型然后再比较</strong>,转换后相等它也会返回true,null == undifined</p><p>!=<br>不等,判断左右两个值是否不等,如果不等则返回true,如果相等则返回false<br>不等也会做自动的类型转换。</p><p><strong>===</strong><br><strong>全等</strong>,判断左右两个值是否全等,它和相等类似,只不过它不会进行自动的类型转换,<br>如果两个值的类型不同,则直接返回false</p><p>!==<br><strong>不全等</strong>,和不等类似,但是它不会进行自动的类型转换,如果两个值的类型不同,它会直接返回true</p><p>特殊的值:<br>null和undefined<br>由于undefined衍生自null,所以<strong>null == undefined</strong> 会返回true。<br>但是 null === undefined 会返回false。<br><strong>NaN</strong><br>NaN不与任何值相等,报告它自身 NaN == NaN //false</p><p>判断一个值是否是NaN<br>使用isNaN()函数</p><h3 id="三元运算符:"><a href="#三元运算符:" class="headerlink" title="三元运算符:"></a>三元运算符:</h3><p>?:<br>语法:条件表达式?语句1:语句2;<br>执行流程:<br>先对条件表达式求值判断,<br>如果判断结果为true,则执行语句1,并返回执行结果<br>如果判断结果为false,则执行语句2,并返回执行结果</p><p>优先级:<br>和数学中一样,JS中的运算符也是具有优先级的,<br>比如 先乘除 后加减 先与 后或<br>具体的优先级可以参考优先级的表格,在表格中越靠上的优先级越高,<br>优先级越高的越优先计算,优先级相同的,从左往右计算。<br>优先级不需要记忆,如果越到拿不准的,使用()来改变优先级。</p><h2 id="流程控制语句"><a href="#流程控制语句" class="headerlink" title="流程控制语句"></a>流程控制语句</h2><p>程序都是自上向下的顺序执行的,<br>通过流程控制语句可以改变程序执行的顺序,或者反复的执行某一段的程序。</p><h3 id="条件分支语句"><a href="#条件分支语句" class="headerlink" title="条件分支语句"></a>条件分支语句</h3><p>条件判断语句也称为if语句<br>语法一:<br> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span>(条件表达式){ </span><br><span class="line">语句... </span><br><span class="line">} </span><br></pre></td></tr></table></figure></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">执行流程: </span><br><span class="line">if语句执行时,会先对条件表达式进行求值判断, </span><br><span class="line">如果值为true,则执行if后的语句 </span><br><span class="line">如果值为false,则不执行 </span><br></pre></td></tr></table></figure><p>语法二:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span>(条件表达式){ </span><br><span class="line">语句... </span><br><span class="line">}<span class="keyword">else</span>{ </span><br><span class="line">语句... </span><br><span class="line">} </span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">执行流程: </span><br><span class="line">if...else语句执行时,会对条件表达式进行求值判断, </span><br><span class="line">如果值为true,则执行if后的语句 </span><br><span class="line">如果值为false,则执行else后的语句 </span><br></pre></td></tr></table></figure><p>语法三:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span>(条件表达式){ </span><br><span class="line">语句... </span><br><span class="line">}<span class="keyword">else</span> <span class="keyword">if</span>(条件表达式){ </span><br><span class="line">语句... </span><br><span class="line">}<span class="keyword">else</span> <span class="keyword">if</span>(条件表达式){ </span><br><span class="line">语句... </span><br><span class="line">}<span class="keyword">else</span> <span class="keyword">if</span>(条件表达式){ </span><br><span class="line">语句... </span><br><span class="line">}<span class="keyword">else</span>{ </span><br><span class="line">语句... </span><br><span class="line">} </span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">执行流程 </span><br><span class="line"> if...else if...else语句执行时,会自上至下依次对条件表达式进行求值判断, </span><br><span class="line">如果判断结果为true,则执行当前if后的语句,执行完成后语句结束。 </span><br><span class="line">如果判断结果为false,则继续向下判断,直到找到为true的为止。 </span><br><span class="line">如果所有的条件表达式都是false,则执行else后的语句 </span><br></pre></td></tr></table></figure><p>1.条件分支语句<br>switch语句<br>语法:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">switch</span>(条件表达式){ </span><br><span class="line"><span class="keyword">case</span> 表达式: </span><br><span class="line">语句... </span><br><span class="line"><span class="keyword">break</span>; </span><br><span class="line"><span class="keyword">case</span> 表达式: </span><br><span class="line">语句... </span><br><span class="line"><span class="keyword">break</span>; </span><br><span class="line"><span class="keyword">case</span> 表达式: </span><br><span class="line">语句... </span><br><span class="line"><span class="keyword">break</span>; </span><br><span class="line"><span class="attr">default</span>: </span><br><span class="line">语句... </span><br><span class="line"><span class="keyword">break</span>; </span><br><span class="line">} </span><br></pre></td></tr></table></figure><p>执行流程:<br>switch…case…语句在执行时,会依次将case后的表达式的值和switch后的表达式的值进行全等比较,<br>如果比较结果为false,则继续向下比较。如果比较结果为true,则从当前case处开始向下执行代码。<br>如果所有的case判断结果都为false,则从default处开始执行代码。</p><h3 id="循环语句"><a href="#循环语句" class="headerlink" title="循环语句"></a>循环语句</h3><p>通过循环语句可以反复执行某些语句多次<br>while循环<br>语法:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">while</span>(条件表达式){ </span><br><span class="line"> 语句... </span><br><span class="line">} </span><br></pre></td></tr></table></figure><p>执行流程:<br>while语句在执行时,会先对条件表达式进行求值判断,<br>如果判断结果为false,则终止循环<br>如果判断结果为true,则执行循环体<br>循环体执行完毕,继续对条件表达式进行求值判断,依此类推</p><p>do…while循环<br>语法:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">do</span>{ </span><br><span class="line">语句... </span><br><span class="line">}<span class="keyword">while</span>(条件表达式) </span><br></pre></td></tr></table></figure><p>执行流程<br>do…while在执行时,会先执行do后的循环体,然后在对条件表达式进行判断,<br>如果判断判断结果为false,则终止循环。<br>如果判断结果为true,则继续执行循环体,依此类推</p><p>和while的区别:<br>while:先判断后执行<br>do…while: 先执行后判断<br>do…while可以确保循环体至少执行一次。</p><p>for循环<br>语法:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(①初始化表达式 ; ②条件表达式 ; ④更新表达式){ </span><br><span class="line"> ③语句... </span><br><span class="line">} </span><br></pre></td></tr></table></figure><p>执行流程:<br>首先执行①初始化表达式,初始化一个变量,<br>然后对②条件表达式进行求值判断,如果为false则终止循环<br>如果判断结果为true,则执行③循环体<br>循环体执行完毕,执行④更新表达式,对变量进行更新。<br>更新表达式执行完毕重复②</p><p>死循环</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">while</span>(<span class="literal">true</span>){ </span><br><span class="line"></span><br><span class="line">} </span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span>(;;){ </span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h1 id="对象(Object)"><a href="#对象(Object)" class="headerlink" title="对象(Object)"></a>对象(Object)</h1><p>对象是JS中的引用数据类型<br><strong>对象是一种复合数据类型,在对象中可以保存多个不同数据类型的属性</strong><br>使用typeof检查一个对象时,会返回object</p><h2 id="对象的分类:"><a href="#对象的分类:" class="headerlink" title="对象的分类:"></a>对象的分类:</h2><p>1.内建对象 </p><ul><li>由ES标准中定义的对象,在任何的ES的实现中都可以使用 </li><li>比如:Math String Number Boolean Function Object….</li></ul><p>2.宿主对象 </p><ul><li>由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象 </li><li>比如 BOM DOM</li></ul><p>3.自定义对象</p><pre><code>- 由开发人员自己创建的对象 </code></pre><p>创建对象<br>方式一:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = <span class="keyword">new</span> <span class="title class_">Object</span>(); </span><br></pre></td></tr></table></figure><p>方式二:<br> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = {}; </span><br></pre></td></tr></table></figure><br><strong>向对象中添加属性</strong><br>语法:<br>对象.属性名 = 属性值;<br><strong>对象[“属性名”] = 属性值;</strong> //这种方式能够使用特殊的属性名</p><p><strong>对象的属性名没有任何要求,不需要遵守标识符的规范,但是在开发中,尽量按照标识符的要求去写。</strong><br>属性值也可以任意的数据类型。</p><p>读取对象中的属性<br>语法:<br>对象.属性名<br>对象[“属性名”] //“属性名”可以使字符串常量,也可以是字符串变量<br>如果读取一个对象中没有的属性,它不会报错,而是返回一个undefined</p><p><strong>删除对象中的属性</strong><br>语法:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">delete</span> 对象.属性名 </span><br><span class="line"><span class="keyword">delete</span> 对象[<span class="string">"属性名"</span>] </span><br></pre></td></tr></table></figure><h2 id="遍历"><a href="#遍历" class="headerlink" title="遍历"></a>遍历</h2><p><strong>使用in检查对象中是否含有指定属性</strong><br>语法:”属性名” in 对象<br>如果在对象中含有该属性,则返回true<br>如果没有则返回false</p><pre><code> 循环遍历对象自身的和继承的可枚举属性(不含Symbol属性). </code></pre><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = {<span class="string">'0'</span>:<span class="string">'a'</span>,<span class="string">'1'</span>:<span class="string">'b'</span>,<span class="string">'2'</span>:<span class="string">'c'</span>}; </span><br><span class="line"> </span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i <span class="keyword">in</span> obj) { </span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(i,<span class="string">":"</span>,obj[i]); </span><br><span class="line">} </span><br></pre></td></tr></table></figure><p><br><strong>使用对象字面量,在创建对象时直接向对象中添加属性</strong><br>语法:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = { </span><br><span class="line"> 属性名:属性值, </span><br><span class="line"> 属性名:属性值, </span><br><span class="line"> 属性名:属性值, </span><br><span class="line"> 属性名:属性值 </span><br><span class="line">} </span><br></pre></td></tr></table></figure><p>基本数据类型和引用数据类型<br>基本数据类型<br>String Number Boolean Null Undefined<br>引用数据类型<br>Object<br><strong>基本数据类型的数据,变量是直接保存的它的值。</strong><br>变量与变量之间是互相独立的,修改一个变量不会影响其他的变量。<br><strong>引用数据类型的数据,变量是保存的对象的引用(内存地址)。</strong><br>如果多个变量指向的是同一个对象,此时修改一个变量的属性,会影响其他的变量。<br>比较两个变量时,对于基本数据类型,比较的就是值,<br>对于引用数据类型比较的是地址,地址相同才相同</p><h2 id="函数(Function)"><a href="#函数(Function)" class="headerlink" title="函数(Function)"></a>函数(Function)</h2><p><strong>函数也是一个对象,也具有普通对象的功能(能有属性)</strong><br>函数中可以封装一些代码,在需要的时候可以去调用函数来执行这些代码<br>使用typeof检查一个函数时会返回function<br>创建函数<br>函数声明</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> 函数名([形参<span class="number">1</span>,形参<span class="number">2.</span>..形参N]){ </span><br><span class="line">语句... </span><br><span class="line">} </span><br></pre></td></tr></table></figure><p>函数表达式</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> 函数名 = <span class="keyword">function</span>(<span class="params">[形参<span class="number">1</span>,形参<span class="number">2.</span>..形参N]</span>){ </span><br><span class="line">语句... </span><br><span class="line">}; </span><br></pre></td></tr></table></figure><p>调用函数<br>语法:函数对象([实参1,实参2…实参N]);<br>fun() sum() alert() Number() parseInt()<br>当我们调用函数时,函数中封装的代码会按照编写的顺序执行</p><p><strong>立即执行函数</strong><br>函数定义完,立即被调用,这种函数叫做立即执行函数<br>立即执行函数往往只会执行一次</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">(<span class="keyword">function</span>(<span class="params">a,b</span>){ </span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"a = "</span>+a); </span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"b = "</span>+b); </span><br><span class="line">})(<span class="number">123</span>,<span class="number">456</span>); </span><br></pre></td></tr></table></figure><p>遍历对象</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> v <span class="keyword">in</span> obj){ </span><br><span class="line"> <span class="variable language_">document</span>.<span class="title function_">write</span>(<span class="string">"property:name ="</span>+v+<span class="string">"value="</span>+obj[v]+<span class="string">"<br/>"</span> ); </span><br><span class="line">} </span><br></pre></td></tr></table></figure><p>形参和实参<br>形参:形式参数<br>定义函数时,可以在()中定义一个或多个形参,形参之间使用,隔开<br>定义形参就相当于在函数内声明了对应的变量但是并不赋值,<br>形参会在调用时才赋值。</p><p>实参:实际参数<br>调用函数时,可以在()传递实参,传递的实参会赋值给对应的形参,<br>调用函数时JS解析器不会检查实参的类型和个数,可以传递任意数据类型的值。<br><strong>如果实参的数量大于形参,多余实参将不会赋值,</strong><br><strong>如果实参的数量小于形参,则没有对应实参的形参将会赋值undefined</strong></p><p><strong>返回值,就是函数执行的结果。</strong><br>使用return 来设置函数的返回值。<br>语法:return 值;<br>该值就会成为函数的返回值,可以通过一个变量来接收返回值<br>return后边的代码都不会执行,一旦执行到return语句时,函数将会立刻退出。<br>return后可以跟任意类型的值,可以是基本数据类型,也可以是一个对象。<br><strong>如果return后不跟值,或者是不写return则函数默认返回undefined。</strong><br>break、continue和return<br>break<br>退出循环<br>continue<br>跳过当次循环<br>return<br>退出函数</p><p><strong>参数,函数的实参也可以是任意的数据类型。</strong></p><p><strong>方法(method)</strong><br>可以将一个函数设置为一个对象的属性,<br>当一个对象的属性是一个函数时,<br>我们称这个函数是该对象的方法。<br>对象.方法名();<br>函数名()</p><h3 id="函数的属性和方法"><a href="#函数的属性和方法" class="headerlink" title="函数的属性和方法"></a>函数的属性和方法</h3><p>call()<br>apply()<br><strong>这两个方法都是函数对象的方法需要通过函数对象来调用</strong><br>通过两个方法可以直接调用函数,并且<strong>可以通过第一个实参来指定函数中this</strong><br>不同的是call是直接传递函数的实参而apply需要将实参封装到一个数组中传递<br><strong>arguments</strong><br>arguments和this类似,都是函数中的隐含的参数<br>arguments是一个类数组元素,它用来封装函数执行过程中的实参<br>所以即使不定义形参,也可以通过arguments来使用实参<br><strong>arguments中有一个属性callee表示当前执行的函数对象</strong></p><p>this(调用函数的那个对象)<br>this是函数的上下文对象,根据函数的调用方式不同会执向不同的对象<br>1.以函数的形式调用时,this是window<br>2.以方法的形式调用时,this是调用方法的对象<br>3.以构造函数的形式调用时,this是新建的那个对象<br>4.使用call和apply调用时,this是指定的那个对象<br>5.在全局作用域中this代表window</p><h2 id="作用域"><a href="#作用域" class="headerlink" title="作用域"></a>作用域</h2><p>作用域简单来说就是一个变量的作用范围。<br>在JS中作用域分成两种:</p><p>1.全局作用域</p><p>直接在script标签中编写的代码都运行在全局作用域中<br><strong>全局作用域在打开页面时创建,在页面关闭时销毁。</strong><br>全局作用域中有一个全局对象window,window对象由浏览器提供,<br>可以在页面中直接使用,它代表的是整个的浏览器的窗口。<br><strong>在全局作用域中创建的变量都会作为window对象的属性保存</strong><br>在全局作用域中创建的函数都会作为window对象的方法保存<br>在全局作用域中创建的变量和函数可以在页面的任意位置访问。<br>在函数作用域中也可以访问到全局作用域的变量。<br>尽量不要在全局中创建变量</p><p>2.函数作用域</p><p>函数作用域是函数执行时创建的作用域,每次调用函数都会创建一个新的函数作用域。<br>函数作用域在函数执行时创建,在函数执行结束时销毁。<br>在函数作用域中创建的变量,不能在全局中访问。<br>当在函数作用域中使用一个变量时,它会先在自身作用域中寻找,<br>如果找到了则直接使用,如果没有找到则到上一级作用域中寻找,<br>如果找到了则使用,找不到则继续向上找,一直会</p><p><strong>变量的声明提前</strong><br>在全局作用域中,使用<strong>var关键字声明的变量会在所有的代码执行之前被声明,但是不会赋值。</strong><br>所以我们可以在变量声明前使用变量。但是不使用var关键字声明的变量不会被声明提前。<br>在函数作用域中,也具有该特性,使用var关键字声明的变量会在函数所有的代码执行前被声明,<br>如果没有使用var关键字声明变量,则变量会变成全局变量</p><p><strong>函数的声明提前</strong><br>在全局作用域中,使用<strong>函数声明创建的函数(function fun(){}),会在所有的代码执行之前被创建</strong>,<br>也就是我们可以在函数声明前去调用函数,但是使用函数表达式(var fun = function(){})创建的函数没有该特性<br>在函数作用域中,使用函数声明创建的函数,会在所有的函数中的代码执行之前就被创建好了。</p><h2 id="this(上下文对象)"><a href="#this(上下文对象)" class="headerlink" title="this(上下文对象)"></a>this(上下文对象)</h2><p>我们每次调用函数时,解析器都会将一个上下文对象作为隐含的参数传递进函数。<br>使用this来引用上下文对象,根据函数的调用形式不同,this的值也不同。</p><p>指向当前对象</p><p>this的不同的情况:<br>1.以函数的形式调用时,this是window<br>2.以方法的形式调用时,this就是调用方法的对象<br>3.以构造函数的形式调用时,this就是新创建的对象</p><h2 id="4-构造函数"><a href="#4-构造函数" class="headerlink" title="4.构造函数"></a>4.构造函数</h2><p>构造函数是专门用来创建对象的函数<br><strong>一个构造函数我们也可以称为一个类</strong><br>通过一个构造函数创建的对象,我们称该对象时这个构造函数的实例<br>通过同一个构造函数创建的对象,我们称为一类对象<br>构造函数就是一个普通的函数,只是他的调用方式不同,<br>如果直接调用,它就是一个普通函数<br>如果使用new来调用,则它就是一个构造函数</p><p>例子:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params">name , age , gender</span>){ </span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">name</span> = name; </span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">age</span> = age; </span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">gender</span> = gender; </span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">sayName</span> = <span class="keyword">function</span>(<span class="params"></span>){ </span><br><span class="line"> <span class="title function_">alert</span>(<span class="variable language_">this</span>.<span class="property">name</span>); </span><br><span class="line"> }; </span><br><span class="line">} </span><br></pre></td></tr></table></figure><p>构造函数的执行流程:<br>1.创建一个新的对象<br>2.将新的对象作为函数的上下文对象(this)<br>3.执行函数中的代码<br>4.将新建的对象返回</p><p><strong>instanceof 用来检查一个对象是否是一个类的实例</strong><br>语法:对象 instanceof 构造函数<br>如果该对象时构造函数的实例,则返回true,否则返回false<br><strong>Object是所有对象的祖先,所以任何对象和Object做instanceof都会返回true</strong></p><p>枚举对象中的属性<br>for…in<br>语法:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> 属性名 <span class="keyword">in</span> 对象){ </span><br><span class="line"> </span><br><span class="line">} </span><br></pre></td></tr></table></figure><p>for…in语句的循环体会执行多次,对象中有几个属性就会执行几次,<br>每次讲一个属性名赋值给我们定义的变量,我们可以通过它来获取对象中的属性</p><h2 id="原型(prototype)"><a href="#原型(prototype)" class="headerlink" title="原型(prototype)"></a>原型(prototype)</h2><p>创建一个函数以后,<strong>解析器都会默认在函数中添加一个数prototype</strong><br>prototype属性指向的是一个对象,这个对象我们称为原型对象。<br>当函数作为构造函数使用,<strong>它所创建的对象中都会有一个隐含的属性执行该原型对象。</strong></p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">这个隐含的属性可以通过对象.<span class="property">__proto__</span>来访问。 </span><br></pre></td></tr></table></figure><p><strong>原型对象就相当于一个公共的区域,凡是通过同一个构造函数创建的对象他们通常都可以访问到相同的原型对象。</strong><br>我们可以将对象中共有的属性和方法统一添加到原型对象中,<br>这样我们只需要添加一次,就可以使所有的对象都可以使用。<br>当我们去访问对象的一个属性或调用对象的一个方法时,它会先自身中寻找,<br>如果在自身中找到了,则直接使用。<br>如果没有找到,则去原型对象中寻找,如果找到了则使用,<br><strong>如果没有找到,则去原型的原型中寻找,</strong>依此类推。直到找到Object的原型为止,Object的原型的原型为null,<br>如果依然没有找到则返回undefined<br><strong>hasOwnProperty()</strong><br>这个方法可以用来检查<strong>对象自身中</strong>是否含有某个属性<br>语法:对象.hasOwnProperty(“属性名”)</p><h2 id="toString方法"><a href="#toString方法" class="headerlink" title="toString方法"></a>toString方法</h2><p>当我们直接在页面中打印一个对象时,事件上是输出的对象的toString()方法的返回值</p><p>如果我们希望在输出对象时不输出[object Object],可以为对象添加一个toString()方法</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//修改Person原型的toString </span></span><br><span class="line"><span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">toString</span> = <span class="keyword">function</span>(<span class="params"></span>){ </span><br><span class="line"><span class="keyword">return</span> <span class="string">"Person[name="</span>+<span class="variable language_">this</span>.<span class="property">name</span>+<span class="string">",age="</span>+<span class="variable language_">this</span>.<span class="property">age</span>+<span class="string">",gender="</span>+<span class="variable language_">this</span>.<span class="property">gender</span>+<span class="string">"]"</span>; </span><br><span class="line">}; </span><br></pre></td></tr></table></figure><h2 id="垃圾回收(GC)"><a href="#垃圾回收(GC)" class="headerlink" title="垃圾回收(GC)"></a>垃圾回收(GC)</h2><p>就像人生活的时间长了会产生垃圾一样,程序运行过程中也会产生垃圾<br>这些垃圾积攒过多以后,会导致程序运行的速度过慢,<br>所以我们需要一个垃圾回收的机制,来处理程序运行过程中产生垃圾<br>当一个对象没有任何的变量或属性对它进行引用,此时我们将永远无法操作该对象,<br>此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序运行变慢,<br>所以这种垃圾必须进行清理。<br>在JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,<br>我们不需要也不能进行垃圾回收的操作<br>我们需要做的只是要将不再使用的对象设置null即可</p><h1 id="数组(Array)"><a href="#数组(Array)" class="headerlink" title="数组(Array)"></a>数组(Array)</h1><p>数组也是一个对象,是一个用来存储数据的对象和Object类似,但是它的存储效率比普通对象要高<br>数组中保存的内容我们称为元素<br>数组使用索引(index)来操作元素<br>索引指由0开始的整数</p><h2 id="数组的操作:"><a href="#数组的操作:" class="headerlink" title="数组的操作:"></a>数组的操作:</h2><p>创建数组</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = <span class="keyword">new</span> <span class="title class_">Array</span>(); </span><br><span class="line"><span class="keyword">var</span> arr = []; </span><br></pre></td></tr></table></figure><p>向数组中添加元素<br>语法;<br>数组对象[索引] = 值;</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">arr[<span class="number">0</span>] = <span class="number">123</span>; </span><br><span class="line">arr[<span class="number">1</span>] = <span class="string">"hello"</span>; </span><br></pre></td></tr></table></figure><p>创建数组时直接添加元素<br>语法:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = [元素<span class="number">1</span>,元素<span class="number">2.</span>...元素N]; </span><br></pre></td></tr></table></figure><p>例子:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = [<span class="number">123</span>,<span class="string">"hello"</span>,<span class="literal">true</span>,<span class="literal">null</span>]; </span><br></pre></td></tr></table></figure><p>获取和修改数组的长度<br>使用length属性来操作数组的长度<br>获取长度:<br>数组.length<br>length获取到的是数组的最大索引+1<br>对于连续的数组,length获取到的就是数组中元素的个数<br>修改数组的长度<br>数组.length = 新长度<br>如果修改后的length大于原长度,则多出的部分会空出来<br>如果修改后的length小于原长度,则原数组中多出的元素会被删除<br>向数组的最后添加元素<br>数组[数组.length] = 值;</p><h2 id="数组的方法"><a href="#数组的方法" class="headerlink" title="数组的方法"></a>数组的方法</h2><table><thead><tr><th>functionName</th><th>function</th><th>usage</th></tr></thead><tbody><tr><td>push()</td><td>用来向数组的末尾添加一个或多个元素,并返回数组新的长度</td><td>语法:数组.push(元素1,元素2,元素N)pop()</td></tr><tr><td>pop()</td><td>用来删除数组的最后一个元素,并返回被删除的元素</td><td></td></tr><tr><td>unshift()</td><td>向数组的开头添加一个或多个元素,并返回数组的新的长度</td><td></td></tr><tr><td>shift()</td><td>删除数组的开头的一个元素,并返回被删除的元素</td><td></td></tr><tr><td>reverse()</td><td>可以用来反转一个数组,它会对原数组产生影响</td><td></td></tr><tr><td>concat()</td><td>可以连接两个或多个数组,它不会影响原数组,而是新数组作为返回值返回</td><td></td></tr><tr><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td></tr></tbody></table><h3 id="slice-sart-end"><a href="#slice-sart-end" class="headerlink" title="slice(sart,[end])"></a>slice(sart,[end])</h3><pre><code> 可以从一个数组中截取指定的元素 该方法不会影响原数组,而是将截取到的内容封装为一个新的数组并返回 参数: 1.截取开始位置的索引(包括开始位置) 2.截取结束位置的索引(不包括结束位置) 第二个参数可以省略不写,如果不写则一直截取到最后 参数可以传递一个负值,如果是负值,则从后往前数 </code></pre><h3 id="splice"><a href="#splice" class="headerlink" title="splice()"></a>splice()</h3><pre><code> 可以用来删除数组中指定元素,并使用新的元素替换 该方法会将删除的元素封装到新数组中返回 参数: 1.删除开始位置的索引 2.删除的个数 3.三个以后,都是替换的元素,这些元素将会插入到开始位置索引的前边 </code></pre><h3 id="join-splitor"><a href="#join-splitor" class="headerlink" title="join([splitor])"></a>join([splitor])</h3><p>可以将一个数组转换为一个字符串<br>参数:<br>需要一个字符串作为参数,这个字符串将会作为连接符来连接数组中的元素<br>如果不指定连接符则默认使用,</p><h3 id="sort"><a href="#sort" class="headerlink" title="sort()"></a>sort()</h3><p>可以对一个数组中的内容进行排序,默认是按照Unicode编码进行排序<br>调用以后,会直接修改原数组。<br>可以自己指定排序的规则,需要一个回调函数作为参数:</p><p>我们可以自己来指定排序的规则<br>我们可以在sort()添加一个回调函数,来指定排序规则,<br>回调函数中需要定义两个形参,<br>浏览器将会分别使用数组中的元素作为实参去调用回调函数<br>使用哪个元素调用不确定,但是肯定的是在数组中a一定在b前边</p><ul><li><p>浏览器会根据回调函数的返回值来决定元素的顺序,<br>如果返回一个大于0的值,则元素会交换位置<br>如果返回一个小于0的值,则元素位置不变<br>如果返回一个0,则认为两个元素相等,也不交换位置</p></li><li><p>如果需要升序排列,则返回 a-b<br>如果需要降序排列,则返回b-a</p></li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span>(<span class="params">a,b</span>){ </span><br><span class="line"><span class="comment">//升序排列 </span></span><br><span class="line"><span class="comment">//return a-b; </span></span><br><span class="line"> </span><br><span class="line"><span class="comment">//降序排列 </span></span><br><span class="line"><span class="keyword">return</span> b-a; </span><br><span class="line">} </span><br></pre></td></tr></table></figure><h2 id="遍历数组"><a href="#遍历数组" class="headerlink" title="遍历数组"></a>遍历数组</h2><p>遍历数组就是将数组中元素都获取到<br>一般情况我们都是使用for循环来遍历数组</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span> ; i<数组.<span class="property">length</span> ; i++){ </span><br><span class="line"> <span class="comment">//数组[i] </span></span><br><span class="line">} </span><br></pre></td></tr></table></figure><p>使用forEach()方法来遍历数组(不兼容IE8)</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">数组.<span class="title function_">forEach</span>(<span class="keyword">function</span>(<span class="params">value , index , obj</span>){ </span><br><span class="line"> </span><br><span class="line">}); </span><br></pre></td></tr></table></figure><p>forEach()方法需要一个回调函数作为参数,<br>数组中有几个元素,回调函数就会被调用几次,<br>每次调用时,都会将遍历到的信息以实参的形式传递进来,<br>我们可以定义形参来获取这些信息。<br>value:正在遍历的元素<br>index:正在遍历元素的索引<br>obj:被遍历对象</p><h1 id="常用类和方法"><a href="#常用类和方法" class="headerlink" title="常用类和方法"></a>常用类和方法</h1><h2 id="包装类"><a href="#包装类" class="headerlink" title="包装类"></a>包装类</h2><p>在JS中为我们提供了<strong>三个包装类:</strong><br>String() Boolean() Number()<br>通过这三个包装类可以创建基本数据类型的对象<br>例子:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> num = <span class="keyword">new</span> <span class="title class_">Number</span>(<span class="number">2</span>); </span><br><span class="line"><span class="keyword">var</span> str = <span class="keyword">new</span> <span class="title class_">String</span>(<span class="string">"hello"</span>); </span><br><span class="line"><span class="keyword">var</span> bool = <span class="keyword">new</span> <span class="title class_">Boolean</span>(<span class="literal">true</span>); </span><br></pre></td></tr></table></figure><p>但是在实际应用中千万不要这么干。</p><p>当我们去操作一个基本数据类型的属性和方法时,<br><strong>解析器会临时将其转换为对应的包装类,然后再去操作属性和方法,</strong><br>操作完成以后再将这个临时对象进行销毁。</p><h2 id="Date"><a href="#Date" class="headerlink" title="Date"></a>Date</h2><p>日期的对象,在JS中通过Date对象来表示一个时间<br>创建对象<br>创建一个当前的时间对象</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> d = <span class="keyword">new</span> <span class="title class_">Date</span>(); </span><br></pre></td></tr></table></figure><p>创建一个指定的时间对象</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> d = <span class="keyword">new</span> <span class="title class_">Date</span>(<span class="string">"月/日/年 时:分:秒"</span>); </span><br></pre></td></tr></table></figure><h3 id="方法:"><a href="#方法:" class="headerlink" title="方法:"></a>方法:</h3><table><thead><tr><th>name</th><th></th></tr></thead><tbody><tr><td>getDate()</td><td>当前日期对象是几日(1-31)</td></tr><tr><td>getDay()</td><td>返回当前日期对象时周几(0-6)<br/> 0 周日<br/> 1 周一 。。。</td></tr><tr><td>getMonth()</td><td>返回当前日期对象的月份(0-11)<br/> 0 一月 1 二月 。。。</td></tr><tr><td>getFullYear()</td><td>从 Date 对象以四位数字返回年份。</td></tr><tr><td>getHours()</td><td>返回 Date 对象的小时 (0 ~ 23)。</td></tr><tr><td>getMinutes()</td><td>返回 Date 对象的分钟 (0 ~ 59)。</td></tr><tr><td>getSeconds()</td><td>返回 Date 对象的秒数 (0 ~ 59)。</td></tr><tr><td>getMilliseconds()</td><td>返回 Date 对象的毫秒(0 ~ 999)。</td></tr><tr><td>getTime()</td><td>返回当前日期对象的时间戳<br/> 时间戳,指的是从1970年月1日 0时0分0秒,<strong>到现在时间的毫秒数</strong><br/> 计算机底层保存时间都是以时间戳的形式保存的。</td></tr><tr><td>Date.now()</td><td>可以获取当前代码执行时的时间戳</td></tr><tr><td>setHours()</td><td>设置 Date 对象中的小时 (0 ~ 23)</td></tr></tbody></table><h2 id="Math"><a href="#Math" class="headerlink" title="Math"></a>Math</h2><p>Math属于一个工具类,它不需要我们创建对象,它里边封装了属性运算相关的常量和方法<br>我们可以直接使用它来进行数学运算相关的操作<br>方法:<br>Math.PI<br>常量,圆周率<br>Math.abs()<br>绝对值运算<br>Math.ceil()<br>向上取整<br>Math.floor()<br>向下取整<br>Math.round()<br>四舍五入取整<br>Math.random()<br>生成一个01之间的随机数<br>生成一个xy之间的随机数<br>Math.round(Math.random()*(y-x)+x);<br>Math.pow(x,y)<br>求x的y次幂<br>Math.sqrt()<br>对一个数进行开方<br>Math.max()<br>求多个数中最大值<br>Math.min()<br>求多个数中的最小值</p><h2 id="字符串的相关的方法"><a href="#字符串的相关的方法" class="headerlink" title="字符串的相关的方法"></a>字符串的相关的方法</h2><p>使用ES6中的字符串新方法</p><p><strong>String.prototype.padStart(maxLength, fillString=’’)</strong> 或 **String.prototype.padEnd(maxLength, fillString=’’)**来填充字符串;</p><p>length<br>获取字符串的长度<br>charAt()<br>根据索引获取指定的字符<br>charCodeAt()<br>根据索引获取指定的字符编码<br><strong>String.fromCharCode()</strong><br><strong>根据字符编码获取字符</strong><br>indexOf()<br>lastIndexOf()<br>从一个字符串中检索指定内容<br>需要一个字符串作为参数,这个字符串就是要检索的内容,<br>如果找到该内容,则会返回其第一次出现的索引,如果没有找到则返回-1。<br>可以指定一个第二个参数,来表示开始查找的位置<br>indexOf()是从前向后找<br>lastIndexOf()是从后向前找<br>slice(start,[end])<br>可以从一个字符串中截取指定的内容,并将截取到内容返回,不会影响原变量<br>参数:<br>第一个:截取开始的位置(包括开始)<br>第二个:截取结束的位置<strong>(不包括结束)</strong><br>可以省略第二个参数,如果省略则一直截取到最后<br>可以传负数,如果是负数则从后往前数<br>substr()<br>和slice()基本一致,不同的是它第二个参数不是索引,而是截取的数量</p><p>substring()<br>和slice()基本一致,不同的是它不能接受负值作为参数,如果设置一个负值,则会自动修正为0,<br><strong>substring()中如果第二个参数小于第一个,自动调整位置</strong><br>toLowerCase()<br>将字符串转换为小写并返回<br>toUpperCase()<br>将字符串转换为大写并返回</p><h3 id="正则表达相关方法"><a href="#正则表达相关方法" class="headerlink" title="正则表达相关方法"></a>正则表达相关方法</h3><p><strong>split()</strong><br>可以根据指定内容将一个字符串拆分为一个数组<br>参数:<br>需要一个字符串作为参数,将会根据字符串去拆分数组<br>可以接收一个正则表达式,此时会根据正则表达式去拆分数组</p><p><strong>match()</strong><br>可以根据正则表达式,从一个字符串中将符合条件的内容提取出来<br>默认情况下我们的match只会找到第一个符合要求的内容,找到以后就停止检索<br>我们可以设置正则表达式为全局匹配模式,这样就会匹配到所有的内容<br>可以为一个正则表达式设置多个匹配模式,且顺序无所谓<br>match()会将匹配到的内容封装到一个数组中返回,即使只查询到一个结果</p><p><strong>replace()</strong><br>可以将字符串中指定内容替换为新的内容<br>参数:<br>1.被替换的内容,可以接受一个正则表达式作为参数<br><strong>2.新的内容</strong> 空串则为删除””<br>默认只会替换第一个</p><p>search()<br>可以搜索字符串中是否含有指定内容<br>如果搜索到指定内容,则会返回第一次出现的索引,如果没有搜索到返回1<br>它可以接受一个正则表达式作为参数,然后会根据正则表达式去检索字符串<br>serach()只会查找第一个,即使设置全局匹配也没用</p><h1 id="正则表达式"><a href="#正则表达式" class="headerlink" title="正则表达式"></a>正则表达式</h1><p>正则用来定义一些字符串的规则,程序可以根据这些规则来判断一个字符串是否符合规则,<br>也可以将一个字符串中符合规则的内容提取出来。<br><strong>创建正则表达式</strong><br>var reg = new RegExp(“正则”,”匹配模式”); 注意:使用构造函数时,由于它的参数是一个字符串,而\是字符串中转义字符,如果要使用\则需要使用\来代替</p><p>var reg = /正则表达式/匹配模式 (匹配模式可以多个一起写:/gi)</p><h2 id="语法:"><a href="#语法:" class="headerlink" title="语法:"></a>语法:</h2><p>匹配模式:<br>i:忽略大小写(ignore)<br>g:全局匹配模式(默认为1次)<br>设置匹配模式时,可以都不设置,也可以设置1个,也可以全设置,设置时没有顺序要求</p><p>正则语法<br>| 或<br>[] 或<br>[^ ] 除了</p><pre><code>**[x-y] x的ascii到y的ascii码之间的值** </code></pre><p>[a-z] 小写字母 <strong>(也可以[e-i])</strong><br>[A-Z] 大写字母<br>[A-z] 任意字母,<strong>但是还包括了其他ASCII在此之中的</strong><br>[0-9] 任意数字</p><p>元符号</p><p>检查一个字符串中是否含有 .<br>. 表示任意字符<br>在正则表达式中使用\作为转义字符<br>. 来表示.<br>\ 表示\</p><p>\w<br>任意字母、数字、_ [A-z0-9_]<br>\W<br>除了字母、数字、_ [ ^A-z0-9_]<br>\d<br>任意的数字 [0-9]<br>\D<br>除了数字 [ ^0-9]<br>\s<br>空格<br>\S<br>除了空格<br>\b<br>单词边界<br>\B<br>除了单词边界</p><p><strong>量词</strong><br>通过量词可以设置一个内容出现的次数<br>量词只对它前边的一个内容起作用<br>{n} 正好出现n次<br>{m,n} 出现mn次<br>{m,} m次以上</p><p>+至少一个,相当于{1,}<br>*个或多个,相当于{0,}<br>? 0个或1个,相当于{0,1}</p><p><strong>边界表达式</strong>(不要在java中用,javaScript中用)<br>^:正则开始<br>$:正则结束 :<strong>注意结束前一个才是结束匹配</strong></p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">reg = <span class="regexp">/^a/</span>; </span><br><span class="line">reg = <span class="regexp">/b$/</span>; </span><br></pre></td></tr></table></figure><h2 id="方法:-1"><a href="#方法:-1" class="headerlink" title="方法:"></a>方法:</h2><p>test()<br>可以用来检查一个字符串是否符合正则表达式<br>如果符合返回true,否则返回false<br>例子</p><p>去掉两端的空格:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> s = <span class="string">" f afa "</span>; </span><br><span class="line">s = s.<span class="title function_">replace</span>(<span class="regexp">/^\s*|\s*$/g</span>,<span class="string">""</span>); </span><br></pre></td></tr></table></figure><h1 id="DOM"><a href="#DOM" class="headerlink" title="DOM"></a>DOM</h1><p>Document Object Model<br>文档对象模型,通过DOM可以来任意来修改网页中各个内容<br>文档<br>文档指的是网页,一个网页就是一个文档<br>对象<br>对象指将网页中的每一个节点都转换为对象<br>转换完对象以后,就可以以一种纯面向对象的形式来操作网页了<br>模型<br>模型用来表示节点和节点之间的关系,方便操作页面<br>节点(Node)<br>节点是构成网页的最基本的单元,网页中的每一个部分都可以称为是一个节点<br>虽然都是节点,但是节点的类型却是不同的<br>常用的节点<br>文档节点 (Document),代表整个网页<br>元素节点(Element),代表网页中的标签<br>属性节点(Attribute),代表标签中的属性<br>文本节点(Text),代表网页中的文本内容</p><h2 id="DOM操作"><a href="#DOM操作" class="headerlink" title="DOM操作"></a>DOM操作</h2><p>DOM查询<br>在网页中浏览器已经为我们提供了<strong>document对象</strong>,<br><strong>它代表的是整个网页,它是window对象的属性,可以在页面中直接使用。</strong><br>document查询方法:<br>根据元素的id属性查询一个元素节点对象:<br>document.getElementById(“id属性值”);<br>根据元素的name属性值查询一组元素节点对象:<br>document.getElementsByName(“name属性值”);<br>根据标签名来查询一组元素节点对象:<br>document.getElementsByTagName(“标签名”);</p><p>元素的属性:<br><strong>读取元素的属性:</strong><br>语法:元素.属性名<br>例子:ele.name<br>ele.id<br>ele.value<br>ele.className<br>注意:class属性不能采用这种方式,<br><strong>读取class属性时需要使用 元素.classNam</strong>e</p><p>修改元素的属性:<br>语法:元素.属性名 = 属性值</p><p>innerHTML<br>使用该属性可以获取或设置元素内部的HTML代码</p><h2 id="事件(Event)"><a href="#事件(Event)" class="headerlink" title="事件(Event)"></a>事件(Event)</h2><p>事件指的是用户和浏览器之间的交互行为。比如:点击按钮、关闭窗口、鼠标移动。。。<br>我们可以为事件来绑定回调函数来响应事件。<br>绑定事件的方式:<br>1.可以在标签的事件属性中设置相应的JS代码<br>例子:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><button onclick=<span class="string">"js代码。。。"</span>>按钮</button> </span><br></pre></td></tr></table></figure><p>2.可以通过为对象的指定事件属性设置回调函数的形式来处理事件<br>例子:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><button id=<span class="string">"btn"</span>>按钮</button> </span><br><span class="line"><span class="language-xml"><span class="tag"><<span class="name">script</span>></span><span class="language-javascript"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="keyword">var</span> btn = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">"btn"</span>); </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> btn.<span class="property">onclick</span> = <span class="keyword">function</span>(<span class="params"></span>){ </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> }; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag"></<span class="name">script</span>></span></span> </span><br></pre></td></tr></table></figure><p>文档的加载<br>浏览器在加载一个页面时,是按照自上向下的顺序加载的,加载一行执行一行。<br>如果将js代码编写到页面的上边,当代码执行时,页面中的DOM对象还没有加载,<br>此时将会无法正常获取到DOM对象,导致DOM操作失败。<br>解决方式一:<br>可以将js代码编写到body的下边</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><body> </span><br><span class="line"><span class="language-xml"><span class="tag"><<span class="name">button</span> <span class="attr">id</span>=<span class="string">"btn"</span>></span>按钮<span class="tag"></<span class="name">button</span>></span></span> </span><br><span class="line"> </span><br><span class="line"><span class="language-xml"><span class="tag"><<span class="name">script</span>></span><span class="language-javascript"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">var</span> btn = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">"btn"</span>); </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">btn.<span class="property">onclick</span> = <span class="keyword">function</span>(<span class="params"></span>){ </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">}; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag"></<span class="name">script</span>></span></span> </span><br><span class="line"></body> </span><br></pre></td></tr></table></figure><p>解决方式二:<br>将js代码编写到window.onload = function(){}中<br>window.onload 对应的回调函数会在整个页面加载完毕以后才执行,<br>所以可以确保代码执行时,DOM对象已经加载完毕了</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><script> </span><br><span class="line"> <span class="variable language_">window</span>.<span class="property">onload</span> = <span class="keyword">function</span>(<span class="params"></span>){ </span><br><span class="line"> <span class="keyword">var</span> btn = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">"btn"</span>); </span><br><span class="line"> btn.<span class="property">onclick</span> = <span class="keyword">function</span>(<span class="params"></span>){ </span><br><span class="line"> }; </span><br><span class="line"> }; </span><br><span class="line"></script> </span><br></pre></td></tr></table></figure><h2 id="DOM查询"><a href="#DOM查询" class="headerlink" title="DOM查询"></a>DOM查询</h2><p>通过具体的元素节点来查询<br>元素.getElementsByTagName()<br>通过标签名查询当前元素的指定后代元素</p><p><strong>子节点包括便签元素中的文本,子元素自包含标签元素</strong></p><p>元素.childNodes<br>获取当前元素的<strong>所有子节点</strong><br><strong>会获取到空白的文本子节点</strong></p><p>childNodes属性会获取包括文本节点在呢的所有节点<br>根据DOM标签标签间空白也会当成文本节点<br>注意:在IE8及以下的浏览器中,不会将空白文本当成子节点,<br>所以该属性在IE8中会返回4个子元素而其他浏览器是9个</p><p>元素.children<br>获取当前元素的<strong>所有子元素</strong></p><p>元素.firstChild<br>获取当前元素的<strong>第一个子节点</strong>,会获取到空白的文本子节点</p><p>元素.lastChild<br>获取当前元素的<strong>最后一个子节点</strong></p><p>元素.parentNode<br>获取当前元素的父元素</p><p>元素.previousSibling<br>获取当前元素的前一个兄弟节点</p><p>previousElementSibling获取前一个兄弟元素,IE8及以下不支持</p><p>元素.nextSibling<br>获取当前元素的后一个兄弟节点</p><p>firstElementChild获取当前元素的第一个子元素<br>firstElementChild不支持IE8及以下的浏览器,<br>如果需要兼容他们尽量不要使用</p><p>innerHTML和innerText<br>这两个属性并没有在DOM标准定义,但是大部分浏览器都支持这两个属性<br>两个属性作用类似,都可以获取到标签内部的内容,<br><strong>不同是innerHTML会获取到html标签,而innerText会自动去除标签</strong><br>如果使用这两个属性来设置标签内部的内容时,没有任何区别的</p><p><strong>读取标签内部的文本内容</strong></p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"></<span class="name">h1</span>></span>h1中的文本内容<span class="tag"></<span class="name">h1</span>></span> </span><br></pre></td></tr></table></figure><p>元素.firstChild.nodeValue</p><h2 id="document对象的其他的属性和方法"><a href="#document对象的其他的属性和方法" class="headerlink" title="document对象的其他的属性和方法"></a>document对象的其他的属性和方法</h2><p>document.all<br><strong>获取页面中的所有元素</strong>,相当于document.getElementsByTagName(“*”);</p><p>document.documentElement<br><strong>获取页面中html根元素</strong></p><p>document.body<br>获取页面中的body元素</p><p>document.getElementsByClassName()<br><strong>根据元素的class属性值查询一组元素节点对象</strong><br>这个方法不支持IE8及以下的浏览器</p><p>document.querySelector()<br><strong>根据CSS选择器去页面中查询一个元素</strong><br>如果匹配到的元素有多个,则它会返回查询到的第一个元素</p><p>document.querySelectorAll()<br>根据CSS选择器去页面中查询一组元素<br>会将匹配到所有元素封装到一个数组中返回,即使只匹配到一个</p><h2 id="DOM修改"><a href="#DOM修改" class="headerlink" title="DOM修改"></a>DOM修改</h2><p>document.createElement(“TagName”)<br>可以用于创建一个元素节点对象,<br>它需要一个标签名作为参数,将会根据该标签名创建元素节点对象,<br>并将创建好的对象作为返回值返回<br>document.createTextNode(“textContent”)<br>可以根据文本内容创建一个文本节点对象</p><p><strong>父节点.appendChild(子节点)</strong><br>向父节点中添加指定的子节点<br><strong>父节点.insertBefore(新节点,旧节点)</strong><br>将一个新的节点插入到旧节点的前边<br>父节点.replaceChild(新节点,旧节点)<br>使用一个新的节点去替换旧节点</p><p><strong>父节点.removeChild(子节点)</strong><br>删除指定的子节点<br>推荐方式:<strong>子节点.parentNode.removeChild(子节点)</strong></p><p><strong>以上方法,实际就是改变了相应元素(标签)的innerHTML的值。</strong></p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">myClick</span>(<span class="string">"btn07"</span>,<span class="keyword">function</span>(<span class="params"></span>){ </span><br><span class="line"> <span class="comment">//向city中添加广州 </span></span><br><span class="line"> <span class="keyword">var</span> city = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">"city"</span>); </span><br><span class="line"> </span><br><span class="line"> <span class="comment">/* </span></span><br><span class="line"><span class="comment">* 使用innerHTML也可以完成DOM的增删改的相关操作 </span></span><br><span class="line"><span class="comment">* 一般我们会两种方式结合使用 </span></span><br><span class="line"><span class="comment">*/</span> </span><br><span class="line"> <span class="comment">//city.innerHTML += "<li>广州</li>"; </span></span><br><span class="line"> </span><br><span class="line"> <span class="comment">//创建一个li </span></span><br><span class="line"> <span class="keyword">var</span> li = <span class="variable language_">document</span>.<span class="title function_">createElement</span>(<span class="string">"li"</span>); </span><br><span class="line"> <span class="comment">//向li中设置文本 </span></span><br><span class="line"> li.<span class="property">innerHTML</span> = <span class="string">"广州"</span>; </span><br><span class="line"> <span class="comment">//将li添加到city中 </span></span><br><span class="line"> city.<span class="title function_">appendChild</span>(li); </span><br><span class="line"> </span><br><span class="line">}); </span><br></pre></td></tr></table></figure><h2 id="DOM对CSS的操作"><a href="#DOM对CSS的操作" class="headerlink" title="DOM对CSS的操作"></a>DOM对CSS的操作</h2><h3 id="读取和修改内联样式"><a href="#读取和修改内联样式" class="headerlink" title="读取和修改内联样式"></a>读取和修改内联样式</h3><p>使用style属性来操作元素的内联样式<br>读取内联样式:<br>语法:元素.style.样式名<br>例子:<br>元素.style.width<br>元素.style.height<br>注意:<strong>如果样式名中带有-,则需要将样式名修改为驼峰命名法将-去掉,然后后的字母改大写</strong><br>比如:backgroundcolor > backgroundColor<br>borderwidth > borderWidth<br>修改内联样式:<br>语法:元素.style.样式名 = 样式值<br><strong>通过style修改和读取的样式都是内联样式</strong>,由于内联样式的优先级比较高,<br>所以我们通过JS来修改的样式,往往会立即生效,<br><strong>但是如果样式中设置了!important,则内联样式将不会生效。</strong></p><h3 id="读取元素的当前样式"><a href="#读取元素的当前样式" class="headerlink" title="读取元素的当前样式"></a>读取元素的当前样式</h3><p>正常浏览器<br><strong>使用getComputedStyle()</strong><br>这个方法是window对象的方法,可以返回一个对象,这个对象中保存着当前元素生效样式<br>参数:<br>1.要获取样式的元素<br>2.可以传递一个伪元素,一般传null<br>例子:<br>获取元素的宽度<br>getComputedStyle(box , null)[“width”];<br>通过该方法读取到样式都是只读的不能修改</p><p>IE8<br><strong>使用currentStyle</strong><br>语法:<br>元素.currentStyle.样式名<br>例子:<br>box.currentStyle[“width”]<br>通过这个属性读取到的样式是只读的不能修改</p><p><strong>实现兼容性</strong></p><p>//对象.属性不存在,不会报错,如果直接寻找对象,(当前作用域到全局作用域)找不到会报错</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">* 定义一个函数,用来获取指定元素的当前的样式 </span></span><br><span class="line"><span class="comment">* 参数: </span></span><br><span class="line"><span class="comment">* obj 要获取样式的元素 </span></span><br><span class="line"><span class="comment">* name 要获取的样式名 </span></span><br><span class="line"><span class="comment">*/</span> </span><br><span class="line"><span class="keyword">function</span> <span class="title function_">getStyle</span>(<span class="params">obj , name</span>){ </span><br><span class="line"><span class="comment">//对象.属性不存在,不会报错,如果直接寻找对象,(当前作用域到全局作用域)找不到会报错 </span></span><br><span class="line"> <span class="keyword">if</span>(<span class="variable language_">window</span>.<span class="property">getComputedStyle</span>){ </span><br><span class="line"> <span class="comment">//正常浏览器的方式,具有getComputedStyle()方法 </span></span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">getComputedStyle</span>(obj , <span class="literal">null</span>)[name]; </span><br><span class="line"> }<span class="keyword">else</span>{ </span><br><span class="line"> <span class="comment">//IE8的方式,没有getComputedStyle()方法 </span></span><br><span class="line"> <span class="keyword">return</span> obj.<span class="property">currentStyle</span>[name]; </span><br><span class="line"> } </span><br><span class="line"> <span class="comment">//return window.getComputedStyle?getComputedStyle(obj , null)[name]:obj.currentStyle[name]; </span></span><br><span class="line">} </span><br></pre></td></tr></table></figure><h3 id="其他的样式相关的属性"><a href="#其他的样式相关的属性" class="headerlink" title="其他的样式相关的属性"></a>其他的样式相关的属性</h3><p>注意:以下样式都是只读的,未指明偏移量都是相对于当前窗口左上角</p><p>clientHeight<br>元素的可见高度,包括元素的内容区和内边距的高度<br>clientWidth<br>元素的可见宽度,包括元素的内容区和内边距的宽度<br>offsetHeight<br>整个元素的高度,包括内容区、内边距、边框<br>offfsetWidth<br>整个元素的宽度,包括内容区、内边距、边框<br>offsetParent<br>当前元素的定位父元素<br>离他最近的开启了定位的祖先元素,如果所有的元素都没有开启定位,则返回body<br>offsetLeft<br>offsetTop<br>当前元素和定位父元素之间的偏移量<br>offsetLeft水平偏移量 offsetTop垂直偏移量</p><p>scrollHeight<br>scrollWidth<br>获取元素滚动区域的高度和宽度</p><p>scrollTop<br>scrollLeft<br>获取元素垂直和水平滚动条滚动的距离</p><p>判断滚动条是否滚动到底<br>垂直滚动条<br>scrollHeight -scrollTop = clientHeight</p><p>水平滚动<br>scrollWidth -scrollLeft = clientWidth</p><h1 id="事件(Event)-1"><a href="#事件(Event)-1" class="headerlink" title="事件(Event)"></a>事件(Event)</h1><h2 id="事件对象"><a href="#事件对象" class="headerlink" title="事件对象"></a>事件对象</h2><p>当响应函数被调用时,浏览器每次都会将一个事件对象作为实参传递进响应函数中,这个事件对象中封装了当前事件的相关信息,比如:鼠标的坐标,键盘的按键,鼠标的按键,滚轮的方向。。</p><p>可以在响应函数中定义一个形参,来使用事件对象,但是在IE8以下浏览器中事件对象没有做完实参传递,而是作为window对象的属性保存</p><p>例子:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">元素.事件 = <span class="keyword">function</span>(<span class="params">event</span>){ </span><br><span class="line"> event = event || <span class="variable language_">window</span>.<span class="property">event</span>; </span><br><span class="line">}; </span><br><span class="line"> </span><br><span class="line">元素.事件 = <span class="keyword">function</span>(<span class="params">e</span>){ </span><br><span class="line">e = e || event; </span><br><span class="line"> </span><br><span class="line">}; </span><br></pre></td></tr></table></figure><p><strong>获取到鼠标的坐标</strong><br>clientX和clientY<br>用于获取鼠标在当前的可见窗口的坐标<br>div的偏移量,是相对于整个页面的</p><p>pageX和pageY 可以获取鼠标相对于当前页面的坐标<br>但是这个两个属性在IE8中不支持,所以如果需要兼容IE8,则不要使用<br>var left = event.clientX;<br>var top = event.clientY;</p><h2 id="事件的冒泡(Bubble)"><a href="#事件的冒泡(Bubble)" class="headerlink" title="事件的冒泡(Bubble)"></a>事件的冒泡(Bubble)</h2><p>事件的冒泡指的是事件向上传导,当后代元素上的事件被触发时,将会导致其祖先元素上的同类事件也会触发。<br>事件的冒泡大部分情况下都是有益的,如果需要取消冒泡,则需要使用事件对象来取消<br><strong>可以将事件对象的cancelBubble设置为true,即可取消冒泡</strong><br>例子:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">元素.事件 = <span class="keyword">function</span>(<span class="params">event</span>){ </span><br><span class="line"> event = event || <span class="variable language_">window</span>.<span class="property">event</span>; </span><br><span class="line"> event.<span class="property">cancelBubble</span> = <span class="literal">true</span>; </span><br><span class="line">}; </span><br></pre></td></tr></table></figure><h2 id="事件的委派"><a href="#事件的委派" class="headerlink" title="事件的委派"></a>事件的委派</h2><p>指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件。</p><p>事件委派是利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能</p><p>我们希望,只绑定一次事件,即可应用到多个的元素上,即使元素是后添加的<br>我们可以尝试将其绑定给元素的共同的祖先元素</p><p><strong>target</strong> : event中的target表示的触发事件的对象</p><h2 id="事件的绑定"><a href="#事件的绑定" class="headerlink" title="事件的绑定"></a>事件的绑定</h2><p>addEventListener()<br>通过这个方法也可以为元素绑定响应函数<br>参数:<br>1.事件的字符串,不要on<br>2.回调函数,当事件触发时该函数会被调用<br>3.是否在捕获阶段触发事件,需要一个布尔值,一般都传false</p><p>使用addEventListener()可以同时为一个元素的相同事件同时绑定多个响应函数,<br>这样当事件被触发时,响应函数将会按照函数的绑定顺序执行</p><p>这个方法不支持IE8及以下的浏览器</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">btn01.<span class="title function_">addEventListener</span>(<span class="string">"click"</span>,<span class="keyword">function</span>(<span class="params"></span>){ </span><br><span class="line"><span class="title function_">alert</span>(<span class="number">1</span>); </span><br><span class="line">},<span class="literal">false</span>); </span><br><span class="line"> </span><br><span class="line">btn01.<span class="title function_">addEventListener</span>(<span class="string">"click"</span>,<span class="keyword">function</span>(<span class="params"></span>){ </span><br><span class="line"><span class="title function_">alert</span>(<span class="number">2</span>); </span><br><span class="line">},<span class="literal">false</span>); </span><br></pre></td></tr></table></figure><p>attachEvent()</p><p>在IE8中可以使用attachEvent()来绑定事件<br>参数:<br>1.事件的字符串,要on<br>2.回调函数</p><p>这个方法也可以同时为一个事件绑定多个处理函数,<br>不同的是它是后绑定先执行,执行顺序和addEventListener()相反</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">btn01.<span class="title function_">attachEvent</span>(<span class="string">"onclick"</span>,<span class="keyword">function</span>(<span class="params"></span>){ </span><br><span class="line"><span class="title function_">alert</span>(<span class="number">1</span>); </span><br><span class="line">}); </span><br><span class="line"> </span><br><span class="line">btn01.<span class="title function_">attachEvent</span>(<span class="string">"onclick"</span>,<span class="keyword">function</span>(<span class="params"></span>){ </span><br><span class="line"><span class="title function_">alert</span>(<span class="number">2</span>); </span><br><span class="line">}); </span><br></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//定义一个函数,用来为指定元素绑定响应函数 </span></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment"> * addEventListener()中的this,是绑定事件的对象 </span></span><br><span class="line"><span class="comment"> * attachEvent()中的this,是window </span></span><br><span class="line"><span class="comment"> * 需要统一两个方法this </span></span><br><span class="line"><span class="comment"> */</span> </span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment"> * 参数: </span></span><br><span class="line"><span class="comment"> * obj 要绑定事件的对象 </span></span><br><span class="line"><span class="comment"> * eventStr 事件的字符串(不要on) </span></span><br><span class="line"><span class="comment"> * callback 回调函数 </span></span><br><span class="line"><span class="comment"> */</span> </span><br><span class="line"><span class="keyword">function</span> <span class="title function_">bind</span>(<span class="params">obj , eventStr , callback</span>){ </span><br><span class="line"> <span class="keyword">if</span>(obj.<span class="property">addEventListener</span>){ </span><br><span class="line"> <span class="comment">//大部分浏览器兼容的方式 </span></span><br><span class="line"> obj.<span class="title function_">addEventListener</span>(eventStr , callback , <span class="literal">false</span>); </span><br><span class="line"> }<span class="keyword">else</span>{ </span><br><span class="line"> <span class="comment">/* </span></span><br><span class="line"><span class="comment"> * this是谁由调用方式决定 </span></span><br><span class="line"><span class="comment"> * callback.call(obj) </span></span><br><span class="line"><span class="comment"> */</span> </span><br><span class="line"> <span class="comment">//IE8及以下 </span></span><br><span class="line"> obj.<span class="title function_">attachEvent</span>(<span class="string">"on"</span>+eventStr , <span class="keyword">function</span>(<span class="params"></span>){ </span><br><span class="line"> <span class="comment">//在匿名函数中调用回调函数 </span></span><br><span class="line"> callback.<span class="title function_">call</span>(obj); </span><br><span class="line"> }); </span><br><span class="line"> } </span><br><span class="line">} </span><br></pre></td></tr></table></figure><h2 id="事件的传播"><a href="#事件的传播" class="headerlink" title="事件的传播"></a>事件的传播</h2><p>关于事件的传播网景公司和微软公司有不同的理解<br>微软公司认为事件应该是由内向外传播,也就是当事件触发时,应该先触发当前元素上的事件,<br>然后再向当前元素的祖先元素上传播,也就说事件应该在冒泡阶段执行。<br>网景公司认为事件应该是由外向内传播的,也就是当前事件触发时,应该先触发当前元素的最外层的祖先元素的事件,<br>然后在向内传播给后代元素<br>W3C综合了两个公司的方案,将事件传播分成了三个阶段<br>1.捕获阶段<br>在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件<br>2.目标阶段<br>事件捕获到目标元素,捕获结束开始在目标元素上触发事件<br>3.冒泡阶段<br>事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件</p><p>如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true<br>一般情况下我们不会希望在捕获阶段触发事件,所以这个参数一般都是false</p><p>IE8及以下的浏览器中没有捕获阶段</p><h2 id="常用事件"><a href="#常用事件" class="headerlink" title="常用事件"></a>常用事件</h2><h3 id="鼠标事件"><a href="#鼠标事件" class="headerlink" title="鼠标事件"></a>鼠标事件</h3><p>拖拽事件</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br></pre></td><td class="code"><pre><span class="line"><!<span class="variable constant_">DOCTYPE</span> html> </span><br><span class="line"> <span class="language-xml"><span class="tag"><<span class="name">html</span>></span> </span></span><br><span class="line"><span class="language-xml"> <span class="tag"><<span class="name">head</span>></span> </span></span><br><span class="line"><span class="language-xml"> <span class="tag"><<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">"UTF-8"</span>></span> </span></span><br><span class="line"><span class="language-xml"> <span class="tag"><<span class="name">title</span>></span><span class="tag"></<span class="name">title</span>></span> </span></span><br><span class="line"><span class="language-xml"><span class="tag"><<span class="name">style</span> <span class="attr">type</span>=<span class="string">"text/css"</span>></span><span class="language-css"> </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"> <span class="selector-id">#box1</span>{ </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="attribute">width</span>: <span class="number">100px</span>; </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="attribute">height</span>: <span class="number">100px</span>; </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="attribute">background-color</span>: red; </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="attribute">position</span>: absolute; </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">} </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="selector-id">#box2</span>{ </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="attribute">width</span>: <span class="number">100px</span>; </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="attribute">height</span>: <span class="number">100px</span>; </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="attribute">background-color</span>: yellow; </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="attribute">position</span>: absolute; </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="attribute">left</span>: <span class="number">200px</span>; </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="attribute">top</span>: <span class="number">200px</span>; </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">} </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"> </span><span class="tag"></<span class="name">style</span>></span> </span></span><br><span class="line"><span class="language-xml"> </span></span><br><span class="line"><span class="language-xml"><span class="tag"><<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span>></span><span class="language-javascript"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="variable language_">window</span>.<span class="property">onload</span> = <span class="keyword">function</span>(<span class="params"></span>){ </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">/* </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * 拖拽box1元素 </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * - 拖拽的流程 </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * 1.当鼠标在被拖拽元素上按下时,开始拖拽 onmousedown </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * 2.当鼠标移动时被拖拽元素跟随鼠标移动 onmousemove </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * 3.当鼠标松开时,被拖拽元素固定在当前位置onmouseup </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> */</span> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//获取box1 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="keyword">var</span> box1 = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">"box1"</span>); </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="keyword">var</span> box2 = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">"box2"</span>); </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="keyword">var</span> img1 = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">"img1"</span>); </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//开启box1的拖拽 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="title function_">drag</span>(box1); </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//开启box2的 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="title function_">drag</span>(box2); </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="title function_">drag</span>(img1); </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">}; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="comment">/* </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * 提取一个专门用来设置拖拽的函数 </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * 参数:开启拖拽的元素 </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> */</span> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">function</span> <span class="title function_">drag</span>(<span class="params">obj</span>){ </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//当鼠标在被拖拽元素上按下时,开始拖拽 onmousedown </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> obj.<span class="property">onmousedown</span> = <span class="keyword">function</span>(<span class="params">event</span>){ </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//设置box1捕获所有鼠标按下的事件 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">/* </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * setCapture() </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * - 只有IE支持,但是在火狐中调用时不会报错, </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * 而如果使用chrome调用,会报错 </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> */</span> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">/*if(box1.setCapture){ </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml">box1.setCapture(); </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml">}*/</span> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> obj.<span class="property">setCapture</span> && obj.<span class="title function_">setCapture</span>(); </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> event = event || <span class="variable language_">window</span>.<span class="property">event</span>; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//div的偏移量 鼠标.clentX - 元素.offsetLeft </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//div的偏移量 鼠标.clentY - 元素.offsetTop </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="keyword">var</span> ol = event.<span class="property">clientX</span> - obj.<span class="property">offsetLeft</span>; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="keyword">var</span> ot = event.<span class="property">clientY</span> - obj.<span class="property">offsetTop</span>; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//为document绑定一个onmousemove事件 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="variable language_">document</span>.<span class="property">onmousemove</span> = <span class="keyword">function</span>(<span class="params">event</span>){ </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> event = event || <span class="variable language_">window</span>.<span class="property">event</span>; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//当鼠标移动时被拖拽元素跟随鼠标移动 onmousemove </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//获取鼠标的坐标 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="keyword">var</span> left = event.<span class="property">clientX</span> - ol; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="keyword">var</span> top = event.<span class="property">clientY</span> - ot; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//修改box1的位置 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> obj.<span class="property">style</span>.<span class="property">left</span> = left+<span class="string">"px"</span>; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> obj.<span class="property">style</span>.<span class="property">top</span> = top+<span class="string">"px"</span>; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> }; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//为document绑定一个鼠标松开事件 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="variable language_">document</span>.<span class="property">onmouseup</span> = <span class="keyword">function</span>(<span class="params"></span>){ </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//当鼠标松开时,被拖拽元素固定在当前位置onmouseup </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//取消document的onmousemove事件 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="variable language_">document</span>.<span class="property">onmousemove</span> = <span class="literal">null</span>; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//取消document的onmouseup事件 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="variable language_">document</span>.<span class="property">onmouseup</span> = <span class="literal">null</span>; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//当鼠标松开时,取消对事件的捕获 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> obj.<span class="property">releaseCapture</span> && obj.<span class="title function_">releaseCapture</span>(); </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> }; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">/* </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml">* 当我们拖拽一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容, </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml">* 此时会导致拖拽功能的异常,这个是浏览器提供的默认行为, </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml">* 如果不希望发生这个行为,则可以通过return false来取消默认行为 </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml">* </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml">* 但是这招对IE8不起作用 </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml">*/</span> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="keyword">return</span> <span class="literal">false</span>; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> }; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">} </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag"></<span class="name">script</span>></span> </span></span><br><span class="line"><span class="language-xml"><span class="tag"></<span class="name">head</span>></span> </span></span><br><span class="line"><span class="language-xml"><span class="tag"><<span class="name">body</span>></span> </span></span><br><span class="line"><span class="language-xml"> </span></span><br><span class="line"><span class="language-xml"> 我是一段文字 </span></span><br><span class="line"><span class="language-xml"> </span></span><br><span class="line"><span class="language-xml"><span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"box1"</span>></span><span class="tag"></<span class="name">div</span>></span> </span></span><br><span class="line"><span class="language-xml"> </span></span><br><span class="line"><span class="language-xml"><span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"box2"</span>></span><span class="tag"></<span class="name">div</span>></span> </span></span><br><span class="line"><span class="language-xml"> </span></span><br><span class="line"><span class="language-xml"><span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"img/an.jpg"</span> <span class="attr">id</span>=<span class="string">"img1"</span> <span class="attr">style</span>=<span class="string">"position: absolute;"</span>/></span> </span></span><br><span class="line"><span class="language-xml"> <span class="tag"></<span class="name">body</span>></span> </span></span><br><span class="line"><span class="language-xml"><span class="tag"></<span class="name">html</span>></span> </span></span><br></pre></td></tr></table></figure><p>滚轮事件:</p><p>onwheel都支持</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br></pre></td><td class="code"><pre><span class="line"><!<span class="variable constant_">DOCTYPE</span> html> </span><br><span class="line"> <span class="language-xml"><span class="tag"><<span class="name">html</span>></span> </span></span><br><span class="line"><span class="language-xml"> <span class="tag"><<span class="name">head</span>></span> </span></span><br><span class="line"><span class="language-xml"> <span class="tag"><<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">"UTF-8"</span>></span> </span></span><br><span class="line"><span class="language-xml"> <span class="tag"><<span class="name">title</span>></span><span class="tag"></<span class="name">title</span>></span> </span></span><br><span class="line"><span class="language-xml"><span class="tag"><<span class="name">style</span> <span class="attr">type</span>=<span class="string">"text/css"</span>></span><span class="language-css"> </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"> <span class="selector-id">#box1</span>{ </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="attribute">width</span>: <span class="number">100px</span>; </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="attribute">height</span>: <span class="number">100px</span>; </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="attribute">background-color</span>: red; </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">} </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"> </span><span class="tag"></<span class="name">style</span>></span> </span></span><br><span class="line"><span class="language-xml"><span class="tag"><<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span>></span><span class="language-javascript"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="variable language_">window</span>.<span class="property">onload</span> = <span class="keyword">function</span>(<span class="params"></span>){ </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//获取id为box1的div </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="keyword">var</span> box1 = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">"box1"</span>); </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//为box1绑定一个鼠标滚轮滚动的事件 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">/* </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * onmousewheel鼠标滚轮滚动的事件,会在滚轮滚动时触发, </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * 但是火狐不支持该属性 </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * 在火狐中需要使用 DOMMouseScroll 来绑定滚动事件 </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * 注意该事件需要通过addEventListener()函数来绑定 </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> */</span> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> box1.<span class="property">onmousewheel</span> = <span class="keyword">function</span>(<span class="params">event</span>){ </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> event = event || <span class="variable language_">window</span>.<span class="property">event</span>; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//event.wheelDelta 可以获取鼠标滚轮滚动的方向 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//向上滚 120 向下滚 -120 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//wheelDelta这个值我们不看大小,只看正负 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//alert(event.wheelDelta); </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//wheelDelta这个属性火狐中不支持 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//在火狐中使用event.detail来获取滚动的方向 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//向上滚 -3 向下滚 3 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//alert(event.detail); </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">/* </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * 当鼠标滚轮向下滚动时,box1变长 </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * 当滚轮向上滚动时,box1变短 </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> */</span> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//判断鼠标滚轮滚动的方向 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="keyword">if</span>(event.<span class="property">wheelDelta</span> > <span class="number">0</span> || event.<span class="property">detail</span> < <span class="number">0</span>){ </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//向上滚,box1变短 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> box1.<span class="property">style</span>.<span class="property">height</span> = box1.<span class="property">clientHeight</span> - <span class="number">10</span> + <span class="string">"px"</span>; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> }<span class="keyword">else</span>{ </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//向下滚,box1变长 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> box1.<span class="property">style</span>.<span class="property">height</span> = box1.<span class="property">clientHeight</span> + <span class="number">10</span> + <span class="string">"px"</span>; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> } </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">/* </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * 使用addEventListener()方法绑定响应函数,取消默认行为时不能使用return false </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * 需要使用event来取消默认行为event.preventDefault(); </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * 但是IE8不支持event.preventDefault();这个玩意,如果直接调用会报错 </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> */</span> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> event.<span class="property">preventDefault</span> && event.<span class="title function_">preventDefault</span>(); </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">/* </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * 当滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动, </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * 这是浏览器的默认行为,如果不希望发生,则可以取消默认行为 </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> */</span> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="keyword">return</span> <span class="literal">false</span>; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> }; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//为火狐绑定滚轮事件 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="title function_">bind</span>(box1,<span class="string">"DOMMouseScroll"</span>,box1.<span class="property">onmousewheel</span>); </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">}; </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">function</span> <span class="title function_">bind</span>(<span class="params">obj , eventStr , callback</span>){ </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="keyword">if</span>(obj.<span class="property">addEventListener</span>){ </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//大部分浏览器兼容的方式 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> obj.<span class="title function_">addEventListener</span>(eventStr , callback , <span class="literal">false</span>); </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> }<span class="keyword">else</span>{ </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">/* </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * this是谁由调用方式决定 </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * callback.call(obj) </span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> */</span> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//IE8及以下 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> obj.<span class="title function_">attachEvent</span>(<span class="string">"on"</span>+eventStr , <span class="keyword">function</span>(<span class="params"></span>){ </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> <span class="comment">//在匿名函数中调用回调函数 </span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> callback.<span class="title function_">call</span>(obj); </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> }); </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> } </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">} </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> </span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag"></<span class="name">script</span>></span> </span></span><br><span class="line"><span class="language-xml"><span class="tag"></<span class="name">head</span>></span> </span></span><br><span class="line"><span class="language-xml"><span class="tag"><<span class="name">body</span> <span class="attr">style</span>=<span class="string">"height: 2000px;"</span>></span> </span></span><br><span class="line"><span class="language-xml"> </span></span><br><span class="line"><span class="language-xml"> <span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"box1"</span>></span><span class="tag"></<span class="name">div</span>></span> </span></span><br><span class="line"><span class="language-xml"> </span></span><br><span class="line"><span class="language-xml"><span class="tag"></<span class="name">body</span>></span> </span></span><br><span class="line"><span class="language-xml"><span class="tag"></<span class="name">html</span>></span> </span></span><br><span class="line"><span class="language-xml"> </span></span><br></pre></td></tr></table></figure><h3 id="键盘事件"><a href="#键盘事件" class="headerlink" title="键盘事件"></a>键盘事件</h3><p>键盘事件:<br>onkeydown<br>按键被按下<br>对于onkeydown来说如果一直按着某个按键不松手,则事件会一直触发<br>当onkeydown连续触发时,第一次和第二次之间会间隔稍微长一点,其他的会非常的快,这种设计是为了防止误操作的发生。<br>onkeyup<br>按键被松开</p><p>键盘事件一般都会绑定给一些可以获取到焦点的对象或者是document</p><p>keyCode</p><p>可以通过keyCode来获取按键的编码<br>通过它可以判断哪个按键被按下<br>除了keyCode,事件对象中还提供了几个属性<br>altKey<br>ctrlKey<br>shiftKey<br>这个三个用来判断alt ctrl 和 shift是否被按下<br>如果按下则返回true,否则返回false</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//console.log(event.keyCode); </span></span><br><span class="line"> </span><br><span class="line"><span class="comment">//判断一个y是否被按下 </span></span><br><span class="line"><span class="comment">//判断y和ctrl是否同时被按下 </span></span><br><span class="line"><span class="keyword">if</span>(event.<span class="property">keyCode</span> === <span class="number">89</span> && event.<span class="property">ctrlKey</span>){ </span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"ctrl和y都被按下了"</span>); </span><br><span class="line">} </span><br></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">input.<span class="property">onkeydown</span> = <span class="keyword">function</span>(<span class="params">event</span>) { </span><br><span class="line"> event = event || <span class="variable language_">window</span>.<span class="property">event</span>; </span><br><span class="line"> <span class="comment">//数字 48 - 57 </span></span><br><span class="line"> <span class="comment">//使文本框中不能输入数字 </span></span><br><span class="line"> <span class="keyword">if</span>(event.<span class="property">keyCode</span> >= <span class="number">48</span> && event.<span class="property">keyCode</span> <= <span class="number">57</span>) { </span><br><span class="line"> <span class="comment">//在文本框中输入内容,属于onkeydown的默认行为 </span></span><br><span class="line"> <span class="comment">//如果在onkeydown中取消了默认行为,则输入的内容,不会出现在文本框中 </span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>; </span><br><span class="line"> } </span><br><span class="line">}; </span><br><span class="line"> </span><br></pre></td></tr></table></figure><h1 id="BOM"><a href="#BOM" class="headerlink" title="BOM"></a>BOM</h1><p>浏览器对象模型(browser object model)<br>BOM可以使我们通过JS来操作浏览器<br>在BOM中为我们提供了一组对象,用来完成对浏览器的操作<br>BOM对象<br>Window<br>代表的是整个浏览器的窗口,同时window也是网页中的全局对象<br>Navigator<br>代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器<br>Location<br>代表当前浏览器的地址栏信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面<br>History<br>代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录<br>由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页<br>而且该操作只在当次访问时有效<br>Screen<br>代表用户的屏幕的信息,通过该对象可以获取到用户的显示器的相关的信息</p><p>这些BOM对象在浏览器中都是作为window对象的属性保存的,<br>可以通过window对象来使用,也可以直接使用</p><h2 id="Navigator"><a href="#Navigator" class="headerlink" title="Navigator"></a>Navigator</h2><p>代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器<br>由于历史原因,Navigator对象中的大部分属性都已经不能帮助我们识别浏览器了<br>一般我们只会使用userAgent来判断浏览器的信息,<br>userAgent是一个字符串,这个字符串中包含有用来描述浏览器信息的内容,<br>不同的浏览器会有不同的userAgent</p><p>火狐的userAgent<br>Mozilla5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko20100101 Firefox50.0</p><p>Chrome的userAgent<br>Mozilla5.0 (Windows NT 6.1; Win64; x64) AppleWebKit537.36 (KHTML, like Gecko) Chrome52.0.2743.82 Safari537.36</p><p>IE8<br>Mozilla4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)</p><p>IE9<br>Mozilla5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)</p><p>IE10<br>Mozilla5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)</p><p>IE11<br>Mozilla5.0 (Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko<br>在IE11中已经将微软和IE相关的标识都已经去除了,所以我们基本已经不能通过UserAgent来识别一个浏览器是否是IE了</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">alert</span>(navigator.<span class="property">appName</span>); </span><br><span class="line"> </span><br><span class="line"><span class="keyword">var</span> ua = navigator.<span class="property">userAgent</span>; </span><br><span class="line"> </span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ua); </span><br><span class="line"> </span><br><span class="line"><span class="keyword">if</span>(firefoxi.<span class="title function_">test</span>(ua)){ </span><br><span class="line"><span class="title function_">alert</span>(<span class="string">"你是火狐!!!"</span>); </span><br><span class="line">}<span class="keyword">else</span> <span class="keyword">if</span>(chromei.<span class="title function_">test</span>(ua)){ </span><br><span class="line"><span class="title function_">alert</span>(<span class="string">"你是Chrome"</span>); </span><br><span class="line">}<span class="keyword">else</span> <span class="keyword">if</span>(msiei.<span class="title function_">test</span>(ua)){ </span><br><span class="line"><span class="title function_">alert</span>(<span class="string">"你是IE浏览器~~~"</span>); </span><br><span class="line">}<span class="keyword">else</span> <span class="keyword">if</span>(<span class="string">"ActiveXObject"</span> <span class="keyword">in</span> <span class="variable language_">window</span>){ </span><br><span class="line"><span class="title function_">alert</span>(<span class="string">"你是IE11,枪毙了你~~~"</span>); </span><br><span class="line">} </span><br></pre></td></tr></table></figure><h2 id="History"><a href="#History" class="headerlink" title="History"></a>History</h2><p>对象可以用来操作浏览器向前或向后翻页<br>length<br>属性,可以获取到当成访问的链接数量<br>back()<br>可以用来回退到上一个页面,作用和浏览器的回退按钮一样<br>forward()<br>可以跳转下一个页面,作用和浏览器的前进按钮一样<br>go()<br>可以用来跳转到指定的页面<br>它需要一个整数作为参数<br>1:表示向前跳转一个页面 相当于forward()<br>2:表示向前跳转两个页面<br>-1:表示向后跳转一个页面<br>-2:表示向后跳转两个页面</p><h2 id="Location"><a href="#Location" class="headerlink" title="Location"></a>Location</h2><p>该对象中封装了浏览器的地址栏的信息<br>如果直接打印location,则可以获取到地址栏的信息(当前页面的完整路径)<br>alert(location);<br>如果直接将location属性修改为一个完整的路径,或相对路径<br>则我们页面会自动跳转到该路径,并且会生成相应的历史记录<br>location = “http:<a href="http://www.baidu.com"/">www.baidu.com"</a>;<br>location = “01.BOM.html”;<br>assign()<br>用来跳转到其他的页面,作用和直接修改location一样<br>reload()<br>用于重新加载当前页面,作用和刷新按钮一样<br>如果在方法中传递一个true,作为参数,则会强制清空缓存刷新页面<br>location.reload(true);<br>replace()<br>可以使用一个新的页面替换当前页面,调用完毕也会跳转页面<br>不会生成历史记录,不能使用回退按钮回退</p><h2 id="window"><a href="#window" class="headerlink" title="window"></a>window</h2><h3 id="定时器"><a href="#定时器" class="headerlink" title="定时器"></a>定时器</h3><p><strong>setInterval()</strong><br>定时调用<br>可以将一个函数,每隔一段时间执行一次<br>参数:<br>1.回调函数,该函数会每隔一段时间被调用一次<br>2.每次调用间隔的时间,单位是毫秒</p><p>返回值:<br>返回一个Number类型的数据<br>这个数字用来作为定时器的唯一标识<br><strong>clearInterval()可以用来关闭一个定时器</strong><br>方法中需要一个定时器的标识作为参数,这样将关闭标识对应的定时器</p><p>clearInterval()可以接收任意参数,<br>如果参数是一个有效的定时器的标识,则停止对应的定时器<br>如果参数不是一个有效的标识,则什么也不做</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> num = <span class="number">1</span>; </span><br><span class="line"><span class="keyword">var</span> timer = <span class="built_in">setInterval</span>(<span class="keyword">function</span>(<span class="params"></span>) { </span><br><span class="line">count.<span class="property">innerHTML</span> = num++; </span><br><span class="line"><span class="keyword">if</span>(num == <span class="number">11</span>) { </span><br><span class="line"><span class="comment">//关闭定时器 </span></span><br><span class="line"><span class="built_in">clearInterval</span>(timer); </span><br><span class="line">} </span><br><span class="line">}, <span class="number">1000</span>); </span><br></pre></td></tr></table></figure><h3 id="延时调用"><a href="#延时调用" class="headerlink" title="延时调用"></a>延时调用</h3><p><strong>setTimeout</strong></p><p>延时调用一个函数不马上执行,而是隔一段时间以后在执行,而且只会执行一次<br>延时调用和定时调用的区别,定时调用会执行多次,而延时调用只会执行一次<br>延时调用和定时调用实际上是可以互相代替的,在开发中可以根据自己需要去选择</p><p>var timer = setTimeout(function(){<br>console.log(num++);<br>},3000);</p><p>使用clearTimeout()来关闭一个延时调用<br>clearTimeout(timer);</p><p>#类的操作</p><p><strong>直接修改元素的类css:</strong></p><p>通过style属性来修改元素的样式,每修改一个样式,浏览器就需要重新渲染一次页面。 这样的执行的性能是比较差的,而且这种形式当我们要修改多个样式时,也不太方便 我希望一行代码,可以同时修改多个样式</p><p>我们可以通过修改元素的class属性来间接的修改样式.这样一来,我们只需要修改一次,即可同时修改多个样式,浏览器只需要重新渲染页面一次,性能比较好,<br>并且这种方式,可以使表现和行为进一步的分离</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">box.<span class="property">className</span> += <span class="string">" b2"</span>;<span class="comment">//注意有空格,添加class属性 </span></span><br></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//定义一个函数,用来向一个元素中添加指定的class属性值 </span></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment"> * 参数: </span></span><br><span class="line"><span class="comment"> * obj 要添加class属性的元素 </span></span><br><span class="line"><span class="comment"> * cn 要添加的class值 </span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> */</span> </span><br><span class="line"><span class="keyword">function</span> <span class="title function_">addClass</span>(<span class="params">obj, cn</span>) { </span><br><span class="line"><span class="keyword">if</span> (!<span class="title function_">hasClass</span>(obj, cn)) { </span><br><span class="line">obj.<span class="property">className</span> += <span class="string">" "</span> + cn; </span><br><span class="line">} </span><br><span class="line">} </span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment"> * 判断一个元素中是否含有指定的class属性值 </span></span><br><span class="line"><span class="comment"> * 如果有该class,则返回true,没有则返回false </span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> */</span> </span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hasClass</span>(<span class="params">obj, cn</span>) { </span><br><span class="line"><span class="keyword">var</span> reg = <span class="keyword">new</span> <span class="title class_">RegExp</span>(<span class="string">"\\b"</span> + cn + <span class="string">"\\b"</span>); </span><br><span class="line"><span class="keyword">return</span> reg.<span class="title function_">test</span>(obj.<span class="property">className</span>); </span><br><span class="line">} </span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment"> * 删除一个元素中的指定的class属性 </span></span><br><span class="line"><span class="comment"> */</span> </span><br><span class="line"><span class="keyword">function</span> <span class="title function_">removeClass</span>(<span class="params">obj, cn</span>) { </span><br><span class="line"><span class="comment">//创建一个正则表达式 </span></span><br><span class="line"><span class="keyword">var</span> reg = <span class="keyword">new</span> <span class="title class_">RegExp</span>(<span class="string">"\\b"</span> + cn + <span class="string">"\\b"</span>); </span><br><span class="line"><span class="comment">//删除class </span></span><br><span class="line">obj.<span class="property">className</span> = obj.<span class="property">className</span>.<span class="title function_">replace</span>(reg, <span class="string">""</span>); </span><br><span class="line">} </span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment"> * toggleClass可以用来切换一个类 </span></span><br><span class="line"><span class="comment"> * 如果元素中具有该类,则删除 </span></span><br><span class="line"><span class="comment"> * 如果元素中没有该类,则添加 </span></span><br><span class="line"><span class="comment"> */</span> </span><br><span class="line"><span class="keyword">function</span> <span class="title function_">toggleClass</span>(<span class="params">obj , cn</span>){ </span><br><span class="line"><span class="comment">//判断obj中是否含有cn </span></span><br><span class="line"><span class="keyword">if</span>(<span class="title function_">hasClass</span>(obj , cn)){ </span><br><span class="line"><span class="comment">//有,则删除 </span></span><br><span class="line"><span class="title function_">removeClass</span>(obj , cn); </span><br><span class="line">}<span class="keyword">else</span>{ </span><br><span class="line"><span class="comment">//没有,则添加 </span></span><br><span class="line"><span class="title function_">addClass</span>(obj , cn); </span><br><span class="line">} </span><br><span class="line">} </span><br></pre></td></tr></table></figure><h1 id="JSON"><a href="#JSON" class="headerlink" title="JSON"></a>JSON</h1><p><strong>JavaScript Object Notation</strong> JS对象表示法</p><h2 id="JSON-格式"><a href="#JSON-格式" class="headerlink" title="JSON 格式"></a>JSON 格式</h2><ol><li>复合类型的值只能是数组或对象,不能是函数、正则表达式对象、日期对象。</li><li>原始类型的值只有四种:字符串、数值(必须以十进制表示)、布尔值和<code>null</code>(不能使用<code>NaN</code>, <code>Infinity</code>, <code>-Infinity</code>和<code>undefined</code>)。</li><li>字符串<strong>必须使用双引号表示</strong>,不能使用单引号。</li><li>对象的键名必须放在双引号里面。</li><li>数组或对象最后一个成员的后面,不能加逗号。</li></ol><p>JS中的对象只有JS自己认识,其他的语言都不认识<br><strong>JSON就是一个特殊格式的字符串</strong>,这个字符串可以被任意的语言所识别,<br>并且可以转换为任意语言中的对象,JSON在开发中主要用来数据的交互<br>JSON和JS对象的格式一样,只不过<strong>JSON字符串中的属性名必须加双引号</strong><br>其他的和JS语法一致<br>JSON分类:<br>1.对象 {}<br>2.数组 []</p><p>JSON中允许的值:<br>1.字符串<br>2.数值<br>3.布尔值<br>4.null<br>5.对象<br>6.数组</p><p>举例:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = <span class="string">'[1,2,3,"hello",true]'</span>; </span><br><span class="line"> </span><br><span class="line"><span class="keyword">var</span> obj2 = <span class="string">'{"arr":[1,2,3]}'</span>; </span><br><span class="line"> </span><br><span class="line"><span class="keyword">var</span> arr2 =<span class="string">'[{"name":"孙悟空","age":18,"gender":"男"},{"name":"孙悟空","age":18,"gender":"男"}]'</span>; </span><br></pre></td></tr></table></figure><p>JSON工具类</p><p>json > js对象<br>JSON.parse()<br>可以将以JSON字符串转换为js对象<br>它需要一个JSON字符串作为参数,会将该字符串转换为JS对象并返回</p><p>var o = JSON.parse(json);<br>var o2 = JSON.parse(arr);</p><p>var obj3 = {name:”猪八戒” , age:28 , gender:”男”};</p><p>JS对象 > JSON<br>JSON.stringify() -ify/fy,表示”使……化。<br>可以将一个JS对象转换为JSON字符串<br>需要一个js对象作为参数,会返回一个JSON字符串</p><p>var str = JSON.stringify(obj3);<br>console.log(str);</p><p>JSON这个对象在IE7及以下的浏览器中不支持,所以在这些浏览器中调用时会报错</p><p></p><h1 id="other"><a href="#other" class="headerlink" title="other"></a>other</h1><h2 id="localStorage"><a href="#localStorage" class="headerlink" title="localStorage"></a>localStorage</h2><p>只读的<code>localStorage</code> 属性允许你访问一个<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Document"><code>Document</code></a> 源(origin)的对象 <a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Storage"><code>Storage</code></a>;其存储的数据能在跨浏览器会话保留。<code>localStorage</code> 类似 <a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/sessionStorage"><code>sessionStorage</code></a>,但其区别在于:存储在 <code>localStorage</code> 的数据可以长期保留;而当页面会话结束——也就是说,当页面被关闭时,存储在 <code>sessionStorage</code> 的数据会被清除 。</p><h2 id="eval"><a href="#eval" class="headerlink" title="eval()"></a>eval()</h2><p>eval()<br>这个函数可以用来执行一段字符串形式的JS代码,并将执行结果返回<br>如果使用eval()执行的字符串中含有{},它会将{}当成是代码块<br>如果不希望将其当成代码块解析,则需要在字符串前后各加一个()</p><p>eval()这个函数的功能很强大,可以直接执行一个字符串中的js代码,<br>但是在开发中尽量不要使用,首先它的执行性能比较差,然后它还具有安全隐患</p><pre><code>var str = '{"name":"孙悟空","age":18,"gender":"男"}'; var obj = eval("("+str+")"); </code></pre><p>编码</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><!DOCTYPE <span class="keyword">html</span>></span> </span><br><span class="line"><span class="tag"><<span class="name">html</span>></span> </span><br><span class="line"><span class="tag"><<span class="name">head</span>></span> </span><br><span class="line"><span class="tag"><<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">"UTF-8"</span>></span> </span><br><span class="line"><span class="tag"><<span class="name">title</span>></span><span class="tag"></<span class="name">title</span>></span> </span><br><span class="line"><span class="tag"><<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span>></span><span class="language-javascript"> </span></span><br><span class="line"><span class="language-javascript"> </span></span><br><span class="line"><span class="language-javascript"><span class="comment">/* </span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"> * 在字符串中使用转义字符输入Unicode编码 </span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"> * \u四位编码 </span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"> */</span> </span></span><br><span class="line"><span class="language-javascript"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"\u2620"</span>); </span></span><br><span class="line"><span class="language-javascript"></span><span class="tag"></<span class="name">script</span>></span> </span><br><span class="line"><span class="tag"></<span class="name">head</span>></span> </span><br><span class="line"><span class="tag"><<span class="name">body</span>></span> </span><br><span class="line"><span class="comment"><!--在网页中使用Unicode编码 </span></span><br><span class="line"><span class="comment">&#编码; 这里的编码需要的是10进制 </span></span><br><span class="line"><span class="comment">--></span> </span><br><span class="line"><span class="tag"><<span class="name">h1</span> <span class="attr">style</span>=<span class="string">"font-size: 200px;"</span>></span><span class="symbol">&#9760;</span><span class="tag"></<span class="name">h1</span>></span> </span><br><span class="line"><span class="tag"><<span class="name">h1</span> <span class="attr">style</span>=<span class="string">"font-size: 200px;"</span>></span><span class="symbol">&#9856;</span><span class="tag"></<span class="name">h1</span>></span> </span><br><span class="line"><span class="tag"></<span class="name">body</span>></span> </span><br><span class="line"><span class="tag"></<span class="name">html</span>></span> </span><br><span class="line"> </span><br></pre></td></tr></table></figure><p>confirm()用于弹出一个带有确认和取消按钮的提示框<br>需要一个字符串作为参数,该字符串将会作为提示文字显示出来<br>如果用户点击确认则会返回true,如果点击取消则返回false<br>var flag = confirm(“确认删除”+name+”吗?”);</p><h2 id="原生js"><a href="#原生js" class="headerlink" title="# 原生js"></a># 原生js</h2><h2 id="原生js实现复制内容到剪切板"><a href="#原生js实现复制内容到剪切板" class="headerlink" title="原生js实现复制内容到剪切板"></a>原生js实现复制内容到剪切板</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">copy</span>(<span class="params"></span>) { </span><br><span class="line"> <span class="keyword">const</span> input = <span class="variable language_">document</span>.<span class="title function_">createElement</span>(<span class="string">"input"</span>); </span><br><span class="line"> <span class="variable language_">document</span>.<span class="property">body</span>.<span class="title function_">appendChild</span>(input); </span><br><span class="line"> input.<span class="title function_">setAttribute</span>(<span class="string">"value"</span>,<span class="variable language_">this</span>.<span class="property">solution</span>.<span class="property">code</span>); </span><br><span class="line"> input.<span class="title function_">select</span>(); </span><br><span class="line"> <span class="keyword">if</span> (<span class="variable language_">document</span>.<span class="title function_">execCommand</span>(<span class="string">"copy"</span>)) { </span><br><span class="line"> <span class="variable language_">document</span>.<span class="title function_">execCommand</span>(<span class="string">"copy"</span>); </span><br><span class="line"> <span class="comment">// console.log("复制成功"); </span></span><br><span class="line"> } </span><br><span class="line"> <span class="variable language_">document</span>.<span class="property">body</span>.<span class="title function_">removeChild</span>(input); </span><br><span class="line">} </span><br></pre></td></tr></table></figure><p><strong><a href="https://github.com/codeOflI/codeOflI.github.io/blob/dev/source/_posts/js-note/javaScript/javaScript.md">github笔记下载地址</a></strong></p>]]></content>
<categories>
<category> JavaScript </category>
</categories>
<tags>
<tag> 笔记 </tag>
<tag> JavaScript </tag>
<tag> 前端 </tag>
</tags>
</entry>
<entry>
<title>剑指Offer Day01</title>
<link href="/2022/03/10/%E5%89%91%E6%8C%87Offer-Day01/"/>
<url>/2022/03/10/%E5%89%91%E6%8C%87Offer-Day01/</url>
<content type="html"><![CDATA[<blockquote><p><strong>前言</strong>:<br>记录一下时间:2022年3月9日。感觉去年的算法课学到的东西过于理论化,但是庆幸自己基础还不错也拿到了很不错的分数。刷算法总归来说有点心血来潮的感觉,其实很早就有打算,但是始终没有给自己安排出来合理的时间,终于今儿在图书馆看到了邻桌的计算机妹子在面对着一次次的LeetCode提交失败,我下定决心了开始刷哈哈哈哈哈,多少有点幸灾乐祸(bushi),但是还是想提升自己。<br>属于是随缘更新了,有的时候题目简单一天可能就做了四五个,有的时候理解起来比较麻烦就少一点,反正还有别的事情要做,这个坚持下来就好。</p></blockquote><h1 id="剑指Offer-Day01"><a href="#剑指Offer-Day01" class="headerlink" title="剑指Offer Day01"></a>剑指Offer Day01</h1><h2 id="剑指-Offer-II-001-整数除法"><a href="#剑指-Offer-II-001-整数除法" class="headerlink" title="剑指 Offer II 001. 整数除法"></a>剑指 Offer II 001. 整数除法</h2><h3 id="题目概述"><a href="#题目概述" class="headerlink" title="题目概述"></a>题目概述</h3><p>给定两个整数 $ a $ 和 $ b $ ,求它们的除法的商 $ a/b $ ,要求不得使用乘号 $ * $、除号 $ / $ 以及求余符号 % 。</p><p>注意:</p><ul><li>整数除法的结果应当截去 $ (truncate) $ 其小数部分,例如:$ truncate(8.345) = 8 $ 以及 $ truncate(-2.7335) = -2 $</li><li>假设我们的环境只能存储 $ 32 $ 位有符号整数,其数值范围是 $ [−2^{31}, 2^{31}−1] $。本题中,如果除法结果溢出,则返回 $ 2^{31} - 1 $</li></ul><p>示例 1:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">输入:a = 15, b = 2</span><br><span class="line">输出:7</span><br><span class="line">解释:15/2 = truncate(7.5) = 7</span><br></pre></td></tr></table></figure><p>示例 2:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">输入:a = 7, b = -3</span><br><span class="line">输出:-2</span><br><span class="line">解释:7/-3 = truncate(-2.33333..) = -2</span><br></pre></td></tr></table></figure><p>示例 3:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">输入:a = 0, b = 1</span><br><span class="line">输出:0</span><br></pre></td></tr></table></figure><p>示例 4:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">输入:a = 1, b = 1</span><br><span class="line">输出:1</span><br></pre></td></tr></table></figure><p>提示:</p><ul><li>$ 2^{31} \le a, b \le 2^{31} - 1 $</li><li>$ b != 0 $</li></ul><h3 id="思路分析"><a href="#思路分析" class="headerlink" title="思路分析"></a>思路分析</h3><p>上来第一道题就开始卡住我,属实是开头有点小破防。</p><ul><li>首先考虑几种特殊情况,不能使用除号来实现除法,那我们就想到了一个比较经典的——快速减法,来实现除法的效果。这里使用了位操作<ul><li>如果说一个数除以另一个数,我们主要看这个被除数里面能包含多少个除数。一个栗子:38里面有多少个4,当38减去4的2指数倍数<strong>(除数右移操作等于扩大一倍)</strong>然后小于当前倍率下的数的时候<strong>(其实就是除数不能再扩大了,这里的扩大是指直接翻倍)</strong>,我们得到当前<strong>右移的次数</strong>,这是当前结果下被数可以消除的除数的次数,<strong>用此时的被除数减去除数,生成新的被除数,并且将除数归为原来的大小。</strong></li><li>还是刚才的例子:38可以被4的4倍( $ 2^{2}$ )16除,能保证差大于当前除数16,但是不能被4的8倍( $ 2^{3}$ )除。所以我们知道了38里面至少有4个4,$ 38 - 16 = 22$ ,以此类推把剩下的被除数中含有的4的个数求出来,当<strong>被除数小于除数</strong>的时候,计算结束,因为我们不需要考虑小数位。</li><li>因为这是位运算,位运算只能是涉及到2的整数倍乘除运算,我们只能等比扩大或者缩小4的2次方倍数(4翻到8,8翻到16……以此类推)</li></ul></li><li>因为数字界限问题,位运算可能会导致溢出,所以我们<strong>统一转化为负数</strong>进行运算,原理一样,但是相应大小号需要变化</li><li>考虑特殊界限问题,除数b等于1的时候<strong>直接输出a</strong>;除数b等于-1而且a等于规定最小整数的时候,如果取反变成正数会<strong>导致溢出</strong>,所以按照题目要求我们返回整型最大值;a等于0结果直接为0</li><li>a,b两个数转化为负数的时候不需要考虑溢出问题</li><li>通过按位异或确定最终结果正负性,并用一个boolean变量flag来保存,用作最后输出</li></ul><h3 id="代码实现-Java"><a href="#代码实现-Java" class="headerlink" title="代码实现 Java"></a>代码实现 Java</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> {</span><br><span class="line"> <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">divide</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b)</span> {</span><br><span class="line"> <span class="keyword">if</span>(a == <span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span>(b == <span class="number">1</span>) <span class="keyword">return</span> a;</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span>(b == -<span class="number">1</span>) <span class="type">return</span> <span class="variable">a</span> <span class="operator">=</span>= Integer.MIN_VALUE ? Integer.MAX_VALUE : -a;</span><br><span class="line"> <span class="type">boolean</span> <span class="variable">positive</span> <span class="operator">=</span> (a ^ b) >= <span class="number">0</span>;</span><br><span class="line"> a = a < <span class="number">0</span> ? a: -a;</span><br><span class="line"> b = b < <span class="number">0</span> ? b: -b;</span><br><span class="line"> <span class="type">int</span> <span class="variable">ans</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span>(a <= b){</span><br><span class="line"> <span class="type">int</span> <span class="variable">base</span> <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line"> <span class="type">int</span> <span class="variable">divisor</span> <span class="operator">=</span> b;</span><br><span class="line"> <span class="keyword">while</span>(a - divisor <= divisor){</span><br><span class="line"> divisor <<= <span class="number">1</span>;</span><br><span class="line"> base <<= <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> ans += base;</span><br><span class="line"> a -= divisor;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> positive ? ans : -ans;</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="剑指-Offer-II-002-二进制加法"><a href="#剑指-Offer-II-002-二进制加法" class="headerlink" title="剑指 Offer II 002. 二进制加法"></a>剑指 Offer II 002. 二进制加法</h2><h3 id="题目概述-1"><a href="#题目概述-1" class="headerlink" title="题目概述"></a>题目概述</h3><p>给定两个 01 字符串 a 和 b ,请计算它们的和,并以二进制字符串的形式输出。</p><p>输入为 <strong>非空</strong> 字符串且只包含数字 1 和 0。</p><p>示例1:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">输入: a = "11", b = "10"</span><br><span class="line">输出: "101"</span><br></pre></td></tr></table></figure><p>示例2:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">输入: a = "1010", b = "1011"</span><br><span class="line">输出: "10101"</span><br></pre></td></tr></table></figure><p>提示:</p><ul><li>每个字符串仅由字符 ‘0’ 或 ‘1’ 组成。</li><li>1 <= a.length, b.length <= 10^4</li><li>字符串如果不是 “0” ,就都不含前导零</li></ul><h3 id="思路分析-1"><a href="#思路分析-1" class="headerlink" title="思路分析"></a>思路分析</h3><p>这道题相对于上一道来讲就比较简单,简单分析一下就写的来代码,但是有的方法还是忍不住去百度一下。</p><ul><li>一位一位去计算就好了,要注意考虑进位的问题,所以单独设置了一个flag变量来检测进位问题</li><li>然后就是简单的,从最后一位开始计算01进位问题,然后在结果的对应位置输出相应的01数值</li><li>如果想每次都是提取到最后一位,就将两个01数字串左移,然后进行运算,再append到结果串</li><li>考虑两个数字串字符位数量不同问题,用0去填充</li><li>考虑最末位进位问题,需要新增一位数位</li><li>因为我们运算的最后一位被最先append到结果里面,所以需要reverse()一下</li></ul><h3 id="代码实现-Java-1"><a href="#代码实现-Java-1" class="headerlink" title="代码实现 Java"></a>代码实现 Java</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> {</span><br><span class="line"> <span class="keyword">public</span> String <span class="title function_">addBinary</span><span class="params">(String a, String b)</span> {</span><br><span class="line"> <span class="type">StringBuilder</span> <span class="variable">ans</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>(); <span class="comment">//结果字符串</span></span><br><span class="line"> <span class="type">int</span> <span class="variable">len_a</span> <span class="operator">=</span> a.length() - <span class="number">1</span>; <span class="comment">//查询最后一位的位置</span></span><br><span class="line"> <span class="type">int</span> <span class="variable">len_b</span> <span class="operator">=</span> b.length() - <span class="number">1</span>;</span><br><span class="line"> <span class="type">int</span> <span class="variable">flag</span> <span class="operator">=</span> <span class="number">0</span>; <span class="comment">//初始进位为0</span></span><br><span class="line"> <span class="keyword">while</span>(len_a >= <span class="number">0</span> || len_b >= <span class="number">0</span>){</span><br><span class="line"> <span class="type">char</span> <span class="variable">temp_a</span> <span class="operator">=</span> len_a >= <span class="number">0</span> ? a.charAt(len_a--) : <span class="string">'0'</span>; </span><br><span class="line"> <span class="type">char</span> <span class="variable">temp_b</span> <span class="operator">=</span> len_b >= <span class="number">0</span> ? b.charAt(len_b--) : <span class="string">'0'</span>;</span><br><span class="line"> <span class="keyword">if</span>(temp_a - <span class="string">'0'</span> + temp_b - <span class="string">'0'</span> > <span class="number">1</span>){</span><br><span class="line"> <span class="keyword">if</span>(flag > <span class="number">0</span>){</span><br><span class="line"> ans.append(<span class="string">'1'</span>);</span><br><span class="line"> flag = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span>{</span><br><span class="line"> ans.append(<span class="string">'0'</span>);</span><br><span class="line"> flag = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span>(temp_a - <span class="string">'0'</span> + temp_b - <span class="string">'0'</span> == <span class="number">1</span>){</span><br><span class="line"> <span class="keyword">if</span>(flag > <span class="number">0</span>){</span><br><span class="line"> ans.append(<span class="string">'0'</span>);</span><br><span class="line"> flag = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span>{</span><br><span class="line"> ans.append(<span class="string">'1'</span>);</span><br><span class="line"> flag = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span>(temp_a - <span class="string">'0'</span> + temp_b - <span class="string">'0'</span> == <span class="number">0</span>){</span><br><span class="line"> <span class="keyword">if</span>(flag > <span class="number">0</span>){</span><br><span class="line"> ans.append(<span class="string">'1'</span>);</span><br><span class="line"> flag = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span>{</span><br><span class="line"> ans.append(<span class="string">'0'</span>);</span><br><span class="line"> flag = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(flag == <span class="number">1</span>) <span class="comment">//若进位还剩1,继续追加</span></span><br><span class="line"> ans.append(flag);</span><br><span class="line"> <span class="keyword">return</span> ans.reverse().toString();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="剑指-Offer-II-003-前-n-个数字二进制中-1-的个数"><a href="#剑指-Offer-II-003-前-n-个数字二进制中-1-的个数" class="headerlink" title="剑指 Offer II 003. 前 n 个数字二进制中 1 的个数"></a>剑指 Offer II 003. 前 n 个数字二进制中 1 的个数</h2><h3 id="题目概述-2"><a href="#题目概述-2" class="headerlink" title="题目概述"></a>题目概述</h3><p>给定一个非负整数 n ,请计算 0 到 n 之间的每个数字的二进制表示中 1 的个数,并输出一个数组。</p><p>示例 1:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">输入: n = 2</span><br><span class="line">输出: [0,1,1]</span><br><span class="line">解释:</span><br><span class="line">0 --> 0</span><br><span class="line">1 --> 1</span><br><span class="line">2 --> 10</span><br></pre></td></tr></table></figure><p>示例2:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">输入: n = 5</span><br><span class="line">输出: [0,1,1,2,1,2]</span><br><span class="line">解释:</span><br><span class="line">0 --> 0</span><br><span class="line">1 --> 1</span><br><span class="line">2 --> 10</span><br><span class="line">3 --> 11</span><br><span class="line">4 --> 100</span><br><span class="line">5 --> 101</span><br></pre></td></tr></table></figure><p>说明 :</p><p>0 <= n <= 105</p><p>进阶:</p><p>给出时间复杂度为O(n*sizeof(integer))的解答非常容易。但你可以在线性时间O(n)内用一趟扫描做到吗?<br>要求算法的空间复杂度为O(n)。<br>你能进一步完善解法吗?要求在C++或任何其他语言中不使用任何内置函数(如 C++ 中的__builtin_popcount)来执行此操作。</p><h3 id="思路分析-2"><a href="#思路分析-2" class="headerlink" title="思路分析"></a>思路分析</h3><ul><li>首先是数组大小需要+1,因为包含了0</li><li>这道题是位运算和动态规划的结合算法,属于是一个我最开始完全没想到的一个操作,很妙</li><li>有一个规律性总结:<ul><li>0含有的1的个数为0,所以f(0)=0;其中f是统计字符1个数的一个构造函数</li><li>如果值i是一个偶数,值i中含有1的个数于值i/2中含有1的个数是一样的,因为是相当于左移了一位,而且i的二进制最后一位必定是0</li><li>如果i是一个奇数,那么f(i) = f(i/2) + 1,因为最后一位是1,必定会少一个1</li></ul></li></ul><h3 id="代码实现-Java-2"><a href="#代码实现-Java-2" class="headerlink" title="代码实现 Java"></a>代码实现 Java</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> {</span><br><span class="line"> <span class="keyword">public</span> <span class="type">int</span>[] countBits(<span class="type">int</span> n) {</span><br><span class="line"> <span class="type">int</span>[] ans = <span class="keyword">new</span> <span class="title class_">int</span>[n + <span class="number">1</span>];</span><br><span class="line"> ans[<span class="number">0</span>] = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i <= n; i++) {</span><br><span class="line"> ans[i] = (i & <span class="number">1</span>) == <span class="number">1</span> ? ans[i - <span class="number">1</span>] + <span class="number">1</span> : ans[i >> <span class="number">1</span>];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 算法 </category>
</categories>
<tags>
<tag> 剑指Offer </tag>
<tag> 算法 </tag>
</tags>
</entry>
<entry>
<title>编译原理概述,语义概述</title>
<link href="/2022/03/09/%E7%BC%96%E8%AF%91%E5%8E%9F%E7%90%86%E6%A6%82%E8%BF%B0-%E8%AF%AD%E4%B9%89%E6%A6%82%E8%BF%B0/"/>
<url>/2022/03/09/%E7%BC%96%E8%AF%91%E5%8E%9F%E7%90%86%E6%A6%82%E8%BF%B0-%E8%AF%AD%E4%B9%89%E6%A6%82%E8%BF%B0/</url>
<content type="html"><![CDATA[<h1 id="编译原理概述-语义概述"><a href="#编译原理概述-语义概述" class="headerlink" title="编译原理概述,语义概述"></a>编译原理概述,语义概述</h1><blockquote><p>笔记摘自NEU编译原理网课</p></blockquote><h2 id="后缀表达式生成"><a href="#后缀表达式生成" class="headerlink" title="后缀表达式生成"></a>后缀表达式生成</h2><p>中缀表达式转后缀表达式可以通过<strong>栈</strong>来实现。</p><ol><li>依次读取输入的表达式,如果是操作数,则把它放入到输出中。</li><li>如果是操作符,栈为空的话直接将该操作符入栈;如果栈非空,则比较栈顶操作符和该操作符优先级,如果栈顶操作符优先级小于该操作符,则该操作符入栈;否则弹出栈顶操作符并将其放入到输出中,直到栈为空或者发现优先级更低的操作符为止。</li><li>如果是括号,比如’(‘和’)’,则特殊处理。如果是’(‘的话,直接入栈;如果是’)’,那么就将栈顶操作符弹出写入到输出中,直到遇到一个对应的’(‘,但是这个’(‘只弹出不写入到输出中。注意:”(“可以理解为优先级最高。</li><li>当表达式读取完毕后,如果栈中还有操作符,则依次弹出操作符并写入到输出中。</li></ol><p><strong>实例:</strong>$$9+(3-1)*3+10 / 2$$</p><ul><li>“9”直接输出</li><li>“+”,”(“进栈</li><li>3直接输出</li><li>“-“进栈</li><li>“1”直接输出</li><li>“)”,找到”(“之前的所有栈中运算符并输出,这里只有一个”-“</li><li>“*”进栈</li><li>“3”直接输出</li><li>“+”优先级低于”<em>“,栈中所有优先级不高于”+”全部输出,”</em>“和”+”输出,本”+”进栈</li><li>“10”直接输出</li><li>“/“进栈</li><li>“2”直接输出</li><li>依次输出”+”,”*”,”+”,”/“</li></ul><p><strong>最后结果:</strong><br>$$9\qquad 3\qquad 1\qquad-\qquad 3\qquad *\qquad +\qquad 10\qquad 2\qquad /\qquad+$$</p><h2 id="解释程序-Interpreter"><a href="#解释程序-Interpreter" class="headerlink" title="解释程序 Interpreter"></a>解释程序 Interpreter</h2><p>解释程序是一种<strong>翻译程序</strong>,将某高级语言翻译成计算机上的低级程序设计语言。</p><p><strong>编译</strong>(Compile)的过程是把整个源程序代码翻译成另外一种代码,翻译后的代码等待被执行或者被优化等等,发生在运行之前,产物是另一份代码。</p><p><strong>解释</strong>(Interpret)的过程是把源程序代码一行一行的读懂,然后一行一行的执行,发生在运行时,产物是运行结果。</p><blockquote><p><strong>编译程序与解释程序的主要区别</strong>:<br>前者有目标程序但是后者无目标程序;前者运行效率高,但是后者更便于人机交互。</p></blockquote><blockquote><p><strong>编译器和解释器的区别</strong>:<br>编译器:输入源代码,源代码被编译成机器码,输出一个可执行程序,但可以不被执行。(存放在磁盘上等待被加载到内存中执行)<br>解释器:输入源代码,直接输出执行结果。一段程序在解释器中运行时可能会被编译多次,每次运行到这段程序时,都会重新编译一次,这样的开销是很大的。</p></blockquote><blockquote><p>其实 JVM 就是一个解释器,而不是一个单纯的编译器。输入 java 字节码 bytecode ,然后直接输出执行结果,而不是输出汇编代码。</p></blockquote><h2 id="编译程序总体结构"><a href="#编译程序总体结构" class="headerlink" title="编译程序总体结构"></a>编译程序总体结构</h2><img src="/2022/03/08/%E7%BC%96%E8%AF%91%E5%8E%9F%E7%90%86%E6%A6%82%E8%BF%B0-%E8%AF%AD%E4%B9%89%E6%A6%82%E8%BF%B0/1.jpg" class=""><ul><li>词法分析:识别单词并分类。生成单词串TOKEN</li><li>语法分析:组词成句及语法错误检查。生成语法树</li><li>语义分析:分析各个语法成分的语义特征。生成语义树</li><li>优化处理:提高目标程序质量的工作。生成优化语义树</li><li>根据优化语义树进行目标代码生成,产生计算机可以识别的语言</li></ul><h3 id="错误处理"><a href="#错误处理" class="headerlink" title="错误处理"></a>错误处理</h3><p>通常,源程序中的错误分为语法错误和语义错误两大类。</p><ul><li>语法错误</li><li>源程序中不符合语法规则或词法规则的错误,可在词法分析或语法分析阶段检测出来。例如,“非法字符”之类的错误可在词法分析时检测出来</li><li>“括号不匹配”、“缺少;”之类的错误,可在语法分析时检测出来</li><li>语义错误</li><li>源程序中不符合语义规则的错误。一般可在语义分析阶段检测出来,有的语义错误却要在运行时才能检测出来。例如,说明错误、作用域错误、类型不一致等错误可在语义分析时检测出来。</li></ul><h3 id="相关术语"><a href="#相关术语" class="headerlink" title="相关术语"></a>相关术语</h3><ul><li>前端(front end):主要依赖于源语言而与目标机器无关的编译阶段。如:词法分析、语法分析、语义分析、中间代码生成、部分优化工作、与前端有关的出错处理工作和符号表管理工作。</li><li>后端(back end):依赖于目标机而一般不依赖于源语言,只与中间代码有关的编译阶段。如:目标代码生成,以及相关出错处理和符号表操作。</li><li>遍(Pass):对源程序或其等价的中间语言程序从头到尾扫视并完成规定任务的过程。每一遍扫视可完成上述一个阶段或多个阶段的工作。具体扫描遍数需要根据语言特性和具体需求来确定,<strong>并不是越多越好也不是越少越好</strong>。</li></ul><h2 id="形式语言"><a href="#形式语言" class="headerlink" title="形式语言"></a>形式语言</h2><ul><li>语言研究至少涉及三个方面:<strong>语义,语法和语用</strong></li><li>形式语言的基本观点是:语言是<strong>符号串的集合</strong></li><li>形式语言研究的基本问题是:研究符号串集合的<strong>表示方法,结构特性以及运算规律</strong></li><li>形式语言是<strong>字母表</strong>上的符号,按一定<strong>规则</strong>组成的所有<strong>字符号串集合</strong>。其中每一个符号被成为<strong>句子</strong>。<ul><li>字母表:元素(符号)的非空有限集合</li><li>符号串:符号的有限序列</li><li>符号串集合:有限个或无限个符号串组成的集合</li><li>规则:以某种形式表达的在一定范围内共同遵守的章程和制度;这里指符号串的组成规则</li></ul></li></ul><h2 id="编译程序的结构"><a href="#编译程序的结构" class="headerlink" title="编译程序的结构"></a>编译程序的结构</h2><ul><li>编译程序的总框<br>按编译过程的划分,编译程序的结构可以划分为相应的模块。<ul><li>词法分析器(扫描器):输入源程序,进行词法分析,输出单词符号。</li><li>语法分析器(分析器):对单词符号进行语法分析,识别出各类语法单位,最终判断输入串是否构成语法上正确的“程序”。</li><li>语义分析和中间代码产生器:按照语义规则对语法分析器导出的语法单位进行语义分析并将它们翻译成一定形式的中间代码。</li><li>优化器:对中间代码进行优化处理。</li><li>目标代码生成器:把中间代码翻译成目标程序。</li></ul></li></ul><h2 id="符号串(集合)的运算"><a href="#符号串(集合)的运算" class="headerlink" title="符号串(集合)的运算"></a>符号串(集合)的运算</h2><h3 id="符号串的运算"><a href="#符号串的运算" class="headerlink" title="符号串的运算"></a>符号串的运算</h3><p>设 $\alpha ,\beta $为两个符号串,则:</p><ol><li><p>连接:$\alpha \bullet \beta = \alpha \beta$</p></li><li><p>或:$\alpha \mid \beta = \alpha ($或者$\beta)$</p></li><li><p>方幂:$\alpha^{n}=\alpha\alpha\alpha…\alpha $ (n个)$ = \alpha^{n-1}\alpha = \alpha\alpha^{n-1}$</p><blockquote><p>$\alpha^{0} = \varepsilon$(<strong>空字符串</strong>,表示什么也没有的空符号串。这里的$\alpha^{0} $不等于1,它表示的是$\alpha $符号串出现的次数)</p></blockquote></li><li><p>闭包:<br>$\alpha$ 的正闭包:$\alpha^{+} = \alpha^{1} \mid \alpha^{2} \mid \alpha^{3} \mid … \mid \alpha^{n} \mid …$<br>$\alpha$ 的星闭包:$\alpha^{*} = \alpha^{0} \mid \alpha^{1} \mid \alpha^{2} \mid … \mid \alpha^{n} \mid …$</p><blockquote><p>闭包通常表示的一种句型,这个句型中会包含有某特符号串,一个句型可以演化出不同的句子。</p></blockquote></li></ol><h3 id="符号串集合的运算"><a href="#符号串集合的运算" class="headerlink" title="符号串集合的运算"></a>符号串集合的运算</h3><p>设 $A ,B $为两个符号串的集合,则:</p><ol><li>乘积: $AB = {xy \mid x\in A 且 y\in B}$</li><li>和:$A\cup B= A+B = { x\mid x\in A 或 x \in B}$</li><li>方幂:$A_{n} = AA…A$ (n个)$AA^{n-1}=A^{n-1}A$<blockquote><p>$A^{0}=\varepsilon$,理由同上<br>$A^{1} = A; A^{2}= AA;A^{3}=AAA…$</p></blockquote></li><li>闭包:<br>$A$的正闭包:$A^{+} = A^{1} \cup A^{2}\cup … \cup A^{n} \cup…$<br>$A$的星闭包:$A^{*} = A^{0} \cup A^{1}\cup … \cup A^{n} \cup…$</li></ol><blockquote><p>例:设$A={a, b} ,则 A^{<em>}=?$<br>$A^{</em>} = { x \mid x=(a \mid b)^{n}, n \ge 0}$<br>推论:若$A$为任一字母表,则$A^{*}$为该字母表上所有符号串(包括空串)的集合。</p></blockquote><h2 id="字符串集合的文法描述"><a href="#字符串集合的文法描述" class="headerlink" title="字符串集合的文法描述"></a>字符串集合的文法描述</h2><h3 id="文法描述"><a href="#文法描述" class="headerlink" title="文法描述"></a>文法描述</h3><ul><li><strong>文法(grammar)</strong> 是有规则的有限集,其中的<strong>上下文无关文法</strong>可以定义为四元组:<br>提供了规则集,就相当于给了一个文法$G(Z)$<br>$$G(Z) = (V_{N}, V_{T}, Z, P)$$</li></ul><p><strong>其中:</strong><br>$V_{N}$:非终结字符集(定义的对象集,如:语法成分等)**[说白了就是能被文法规则推导替换的句子]**<br>$V_{T}$:终结符集(字母表)**[说白了就是不能被文法规则推导替换的句子,最简化]**<br>$Z$:开始符号(研究范畴中最大的定义对象,一般是需要自行定义)<br>$P$:规则集(又称产生式集)**[说白了就是定义的推导规则]**</p><h3 id="文法定义语言"><a href="#文法定义语言" class="headerlink" title="文法定义语言"></a>文法定义语言</h3><p>给定文法$G(Z)$之后,得到$L(G)$则是通过文法G定义的语言:</p><p>$$L(G) = { x \mid Z \Rightarrow + x,x\in (V_{T})^{*} }$$</p><blockquote><p>公式中间的加号应该是在右箭头<strong>上方</strong>的,表示的是连续推导的意思,至少推导一次!</p></blockquote><p>从<strong>开始符号</strong>出发,对符号串中的<strong>定义对象</strong>,采用<strong>推导</strong>的办法(用其规则右部替换左部)产生新的符号串,如此进行,直到新符号串中不再出现定义的对象为止,最终的符号串就是一个<strong>句子</strong>。</p><h4 id="标识符文法"><a href="#标识符文法" class="headerlink" title="标识符文法"></a>标识符文法</h4><blockquote><p>标识符:指<strong>字母</strong>开头的字母,数字序列</p></blockquote><p>$$G(Z)=(V_{n}, V_{T}, Z, P)$$<br>$V_{N}={I(标识符),A(标识符尾)}$<br>$V_{T}={l(字母),d(数字)}$<br>$Z=I$<br>$P:I\rightarrow lA \mid l;\qquad A\rightarrow lA \mid dA \mid \varepsilon;$</p><h5 id="标识符文法求解"><a href="#标识符文法求解" class="headerlink" title="标识符文法求解"></a>标识符文法求解</h5><p>从终结符集开始,也就是我们常说的最底层开始。</p><ol><li>求解A:$A = (l \mid d) A,A = (l \mid d)^{2} ,A = (l \mid d)^{3}…,A = (l \mid d)^{n}A,(n\ge 0)$</li><li>求解I:$I =lA \mid l = l(l \mid d)^{n}A,(n\ge 0)$</li></ol><h4 id="无符号整数文法"><a href="#无符号整数文法" class="headerlink" title="无符号整数文法"></a>无符号整数文法</h4><p>$$G(N)=({N}, d, {N}, P)$$<br>$P: N\rightarrow dN \mid d$<br>N是自然数</p><h4 id="算术表达式文法"><a href="#算术表达式文法" class="headerlink" title="算术表达式文法"></a>算术表达式文法</h4><p>$$G(Z)=(V_{N}, V_{T}, Z, P)$$</p><p>$V_{N}={E(算术表达式),T(项), F(因式)}$</p><p>$V_{T}={i(变量或常数),=,-,*,/,(,)}$</p><p>$Z=E$</p><p>$P:E\rightarrow T \mid E +T\mid E-T; \qquad T\rightarrow F\mid T*F \mid T/F; \quad F \rightarrow i \mid (E)$<br>层次嵌套结构:表达式 $\rightarrow $ 项 $\rightarrow$ 因式 $\rightarrow$ 表达式</p><h3 id="主要语法成分定义"><a href="#主要语法成分定义" class="headerlink" title="主要语法成分定义"></a>主要语法成分定义</h3><blockquote><p>文法有两种基本运算:<strong>推导,归约</strong>。</p></blockquote><p>设:$x,y \in (V_{N}+V_{T})^{*},A\rightarrow \alpha \in P$</p><ol><li><p>直接推导($\Rightarrow$) $xAy \Rightarrow x \alpha y$<br> 即:指用产生式的右部符号串<strong>替换</strong>左部非终结符。 </p><ul><li>加推导($\Rightarrow + 加号在箭头上面$)</li></ul><p> <strong>当且仅当</strong>$\alpha \Rightarrow \alpha_{1} \Rightarrow \alpha_{2} \Rightarrow \alpha_{3} \Rightarrow … \Rightarrow \beta$<br> 即:指一步或一步以上的直接推导运算。</p><ul><li>星推导($\Rightarrow * 星号在箭头上面$)</li></ul><p> <strong>当且仅当</strong>$\alpha = \beta 或\alpha \Rightarrow \alpha_{1} \Rightarrow \alpha_{2} \Rightarrow \alpha_{3} \Rightarrow … \Rightarrow \beta$<br> 即:指零步或零步以上的直接推导运算。</p></li><li><p>直接归约($\Rightarrow \bullet 点在箭头下面$)<br> 即:直接归约是直接推导的<strong>逆运算</strong>,用产生式的左部非终结符<strong>替换</strong>右部符号串。</p><ul><li>加归约($\Rightarrow + \bullet 加号在箭头上面,点在箭头下面$)<br> <strong>当且仅当</strong>$\alpha \Rightarrow \bullet \alpha_{1} \Rightarrow \bullet \alpha_{2} \Rightarrow \bullet\alpha_{3} \Rightarrow \bullet… \Rightarrow \bullet\beta$<br> 即:指一步或一步以上的直接归约运算。</li><li>星归约($\Rightarrow * \bullet 星号在箭头上面,点在箭头下面$)<br> <strong>当且仅当</strong>$\alpha = \beta 或\alpha \Rightarrow \bullet\alpha_{1} \Rightarrow \bullet\alpha_{2} \Rightarrow \bullet\alpha_{3} \Rightarrow\bullet … \Rightarrow \bullet\beta$<br> 即:指零步或零步以上的直接归约运算。<blockquote><p>※ 实用中最常见的两种运算:</p></blockquote></li></ul></li></ol><p><strong>最左推导</strong>($+ \Rightarrow l,加号在箭头上面,l在箭头下面$):每次推导皆最左非终结符优先。<br><strong>最左归约</strong>($+ \Rightarrow \bullet l,加号在箭头上面,l和\bullet在箭头下面$):每次归约皆最左可归约串优先。</p><p>最左推导/归约是指对需要推导的式子转化成<strong>目标格式</strong>,需要进行的向右/向左推导,并不是说选择推导结果的<strong>最左侧选项</strong>。(格式要对上才能运算出最后结果)</p><h4 id="句型,句子,语法树"><a href="#句型,句子,语法树" class="headerlink" title="句型,句子,语法树"></a>句型,句子,语法树</h4><p>设有文法:$G(Z)=(V_{n}, V_{T}, Z, P)$</p><ul><li>句型:是由文法开始符号加推导出的任一符号串。<br>$若有:Z \Rightarrow + \alpha,则\alpha 是句型$</li><li>句子:是由开始符号加推导出的任一终结符号串。<br>$若有:Z \Rightarrow + \alpha,且 \alpha \in (V_{T})^{*},则\alpha 是句型$</li><li>语法树:句型(句子)产生过程的一种树结构表示。<ul><li>树根–开始符号;树叶—给定的句型(句子)。</li></ul></li></ul><h5 id="语法树的构造算法"><a href="#语法树的构造算法" class="headerlink" title="语法树的构造算法"></a>语法树的构造算法</h5><blockquote><p>关于语法树:<br><strong>子树</strong> :以任何具有分支的结点为根所形成的树,称为原树的子树。<br><strong>简单子树</strong> :仅具有<strong>单层分支</strong>的子树。</p></blockquote><ol><li><p>置树根为开始符号</p></li><li><p>若采用了推导产生式: $A \rightarrow x_{1},x_{2},…,x_{n}$,则有子树:</p><img src="/2022/03/08/%E7%BC%96%E8%AF%91%E5%8E%9F%E7%90%86%E6%A6%82%E8%BF%B0-%E8%AF%AD%E4%B9%89%E6%A6%82%E8%BF%B0/2.jpg" class=""></li><li><p>重复步骤2,直到再没有推导产生式为止</p><blockquote><p>如此构造的语法树,其<strong>全体树叶</strong>(自左至右)恰好是给定的句型。</p></blockquote></li></ol><h3 id="短语,简单短语,句柄"><a href="#短语,简单短语,句柄" class="headerlink" title="短语,简单短语,句柄"></a>短语,简单短语,句柄</h3><p>设文法 $G(Z) , x\alpha y$ 是一个句型,则:</p><ol><li><p>短语<br>若 $Z\Rightarrow + xAy \Rightarrow + x \alpha y \Rightarrow …$<br>则 $\alpha$是句型关于 $xAy$ 的一个短语($A$是$\alpha$的名字)<br>任一<strong>子树</strong>的<strong>树叶全体</strong>(具有共同<strong>祖先</strong>的叶节点符号串)皆为短语</p></li><li><p>简单短语<br>若 $Z\Rightarrow + xAy \Rightarrow x \alpha y \Rightarrow …$<br>则 $\alpha$是句型关于 $xAy$ 的一个短语($A$是$\alpha$的名字)<br>任一<strong>简单子树</strong>的<strong>树叶全体</strong>(具有共同<strong>父亲</strong>的叶节点符号串)皆为简单短语</p><blockquote><p>其实就是两个式子是直接上下级</p></blockquote></li><li><p>句柄<br>一个句型的最左简单短语称为该句型的句柄</p></li></ol><p>放个<strong>栗子</strong>:</p><img src="/2022/03/08/%E7%BC%96%E8%AF%91%E5%8E%9F%E7%90%86%E6%A6%82%E8%BF%B0-%E8%AF%AD%E4%B9%89%E6%A6%82%E8%BF%B0/3.jpg" class=""><h3 id="两种特性文法"><a href="#两种特性文法" class="headerlink" title="两种特性文法"></a>两种特性文法</h3><p>设有文法:$G(Z)=(V_{n}, V_{T}, Z, P)$</p><h4 id="递归文法"><a href="#递归文法" class="headerlink" title="递归文法"></a>递归文法</h4><p>设:$A \in V_{N};x,y \in (V_{N}+V_{T})^{<em>}, $ 则:若$A \Rightarrow + xAy, $则称该文法具有*<em>递归性</em></em><br>若:$A \rightarrow A\alpha,$ 称该文法具有<strong>直接左递归性</strong>,又称直接左递归文法;<br>若:$A \rightarrow \alpha A,$ 称该文法具有<strong>直接右递归性</strong>,又称直接右递归文法。</p><blockquote><p>递归文法是定义无限语言的工具(递归文法定义的语言有无限个句子)</p></blockquote><h4 id="二义性文法"><a href="#二义性文法" class="headerlink" title="二义性文法"></a>二义性文法</h4><p>若文法中存在这样的句型,它具有两棵不同的语法树,则称该文法是二义性文法。</p><ul><li>一个栗子:算数表达式的另一种文法</li></ul><p>$ G(E)^{‘}: E \rightarrow E+E \mid E-E \mid E*E \mid E/E \mid (E) \mid i $ </p><p>其中$ i $是变量或者常数,针对于这个文法,句型$ i*i+i $有两个不一样的语法树。所以$ G(E)^{‘} $ 是二义性文法。</p><img src="/2022/03/08/%E7%BC%96%E8%AF%91%E5%8E%9F%E7%90%86%E6%A6%82%E8%BF%B0-%E8%AF%AD%E4%B9%89%E6%A6%82%E8%BF%B0/4.jpg" class=""><h3 id="文法的等价替换"><a href="#文法的等价替换" class="headerlink" title="文法的等价替换"></a>文法的等价替换</h3><p>假设 $G_{1}, G_{2}$ 是两个文法,若 $L(G_{1}) = L(G_{2}), $ 则称$G_{1}, G_{2}$等价,记作 $G_{1}\equiv G_{2}$。文法的等价性是指他们所定义的语言是完全一致的。</p><blockquote><p><strong>如何判断是不是等价文法?</strong><br>拿到两个文法之后,写出他们的所有语言,然后进行对照,如果完全一致,那么就说明写出来语言的两个文法是等价文法。必须完全一致!【间接说明了,描述一个语言所使用的文法也并不是唯一的】</p></blockquote><h4 id="文法的变换方法"><a href="#文法的变换方法" class="headerlink" title="文法的变换方法"></a>文法的变换方法</h4><p>必要的时候对文法进行改写,当然改写后的文法要与原文法等价。通常称为<strong>文法变换</strong></p><ul><li>删除无用的产生式(文法的化简)</li><li>删除 $\varepsilon$ 产生式【如果文法的右部推导出来的是一个空串,我们会把它删除】</li><li>常用的三种文法变换的方法<ul><li>必选项法</li><li>可选项法</li><li>重复可选项法</li></ul></li></ul><h5 id="文法的变换01——文法化简"><a href="#文法的变换01——文法化简" class="headerlink" title="文法的变换01——文法化简"></a>文法的变换01——文法化简</h5><p>文法的化简是指消除如下无用产生式:</p><ol><li>删除 $A \rightarrow A$ 形式的产生式(自定己)</li><li>删除不能从其中推导出终结符串的产生式(不终结)</li><li>删除在推导中永不使用的产生式(不可用)</li></ol><p><strong>第二步</strong>的相关算法(删除不产生终结式的产生式)</p><p>$ V_{VT} $是一个用于存储以<strong>终结式</strong>为起点<strong>回推导</strong>的文法的集合</p><ol><li>若有 $A \rightarrow \alpha $,且 $ \alpha \in (V_{T})^{*} $;则令 $A \in V_{VT} $;</li><li>若有 $B \rightarrow \beta $,且 $ \beta \in (V_{T}+V_{VT})^{*} $;则令 $ B \in V_{VT} $;</li><li>重复1,2两步,直到 $ V_{VT} $ 集合稳定没有变化为止</li><li>删除<strong>不存在</strong>于 $ V_{VT} $ 中的所有文法(整个文法连同其产生式一起删除)</li></ol><blockquote><p><strong>第三步</strong>的算法实际上和第二步的思路基本一致,但是是从起始<strong>标识符</strong>开始<strong>正向推导筛选</strong>的过程</p></blockquote><h5 id="文法的变换02——删除-varepsilon-产生式"><a href="#文法的变换02——删除-varepsilon-产生式" class="headerlink" title="文法的变换02——删除 $\varepsilon$ 产生式"></a>文法的变换02——删除 $\varepsilon$ 产生式</h5><p>目的就是把所有的 $\varepsilon$ 全部干掉!!</p><ol><li>首先构造出可以推出空出空串的非终结符集: $V_{\varepsilon}$<ul><li>若有 $ A \rightarrow \varepsilon$ ;则令: $A\in V_{\varepsilon}$</li><li>若有 $ B \rightarrow A_{1} A_{2}…A_{n}…$,且全部 $A_{i}\in V_{\varepsilon}$ ;则令: $B\in V_{\varepsilon}$</li><li>重复1,2两步,直到 $V_{\varepsilon}$ 集合稳定没有变化为止</li></ul></li><li>删除 $G(Z)$ 中的 $ A \rightarrow \varepsilon$ 形式的产生式</li><li>依次改写 $G(Z)$ 中的产生式 $A \rightarrow X_{1} X_{2}…X_{i}$:若有 $X_{i}\in V_{\varepsilon}$ 则用 $(X_{i} \mid \varepsilon)$ 替换之(一个分裂为两个)</li></ol><blockquote><p>在真正进行分析的时候,我们一般认为<strong>终结符集</strong>(一般为小写字母表示)如果进行推导的话也可以推导出空集 $\varepsilon$ </p></blockquote><p>举一个栗子:</p><img src="/2022/03/08/%E7%BC%96%E8%AF%91%E5%8E%9F%E7%90%86%E6%A6%82%E8%BF%B0-%E8%AF%AD%E4%B9%89%E6%A6%82%E8%BF%B0/5.jpg" class=""><p>这里就提到了刚才在上面标注的,终结符集 $b$ 也可以运用步骤 1 中可推导出 $\varepsilon$ 的性质,在步骤 2 将 $B$ 划分为 $V_{\varepsilon}$ 中。</p><h5 id="文法的变换03——常用的三种文法变换的方法"><a href="#文法的变换03——常用的三种文法变换的方法" class="headerlink" title="文法的变换03——常用的三种文法变换的方法"></a>文法的变换03——常用的三种文法变换的方法</h5><blockquote><p>基本思想:扩展文法,引进<strong>新的描述符号</strong></p></blockquote><ol><li><p>必选项法(圆括号”( )”法)<br>$ (\alpha \mid \beta) = \alpha 或者 \beta $,<strong>必须是二者之一</strong><br>$ A \rightarrow a(\alpha \mid \beta) \Leftrightarrow a\alpha \mid a\beta \Leftrightarrow A \rightarrow a A^{‘}\qquad A^{‘} \rightarrow \alpha \mid \beta $</p></li><li><p>可选项法(花括号”〔 〕”法)<br>$〔\alpha 〕 = \alpha 或者 \varepsilon $,<strong>可选也可不选</strong><br>$ S \rightarrow \alpha \mid \alpha \beta \Leftrightarrow \alpha〔\beta 〕\Leftrightarrow S \rightarrow \alpha S^{‘} \qquad S^{‘} \rightarrow \beta \mid \varepsilon $</p></li><li><p>重复和选项法(花括号法)<br>$ { \alpha } = \varepsilon 或 \alpha 或 \alpha \alpha 或 \alpha \alpha \alpha … $<br>$A \rightarrow A \beta \mid \alpha \Leftrightarrow \alpha {\beta } \Leftrightarrow A \rightarrow \alpha A^{‘} \qquad A^{‘} \rightarrow \beta \mid \varepsilon $</p><blockquote><p>此文法常用来消除文法的<strong>直接左递归</strong></p></blockquote></li></ol><h3 id="形式语言的分类"><a href="#形式语言的分类" class="headerlink" title="形式语言的分类"></a>形式语言的分类</h3><p>chomsky 把形式语言分为四类,分别由四类文法定义;四类文法的区别在于<strong>产生式的形式</strong>不同:</p><ol><li>0 型语言 由 0 型文法定义,又称无限制文法。产生式形式为 $\alpha \rightarrow \beta$</li><li>1 型语言 由 1 型文法定义,又称上下文有关文法。产生形式为 $xAy \rightarrow x\beta y$</li><li>2 型语言 由 2 型文法定义,又称上下文无关文法。产生式形式为 $A \rightarrow \beta$</li><li>3 型语言 由 3 型文法定义,又称正规文法。产生式形式为 $A \rightarrow aB \qquad A \rightarrow a \qquad A \rightarrow \varepsilon$</li></ol>]]></content>
<categories>
<category> 编译原理 </category>
</categories>
<tags>
<tag> 笔记 </tag>
<tag> 编译原理 </tag>
</tags>
</entry>
<entry>
<title>分类,回归,聚类,降维</title>
<link href="/2022/03/07/%E5%88%86%E7%B1%BB-%E5%9B%9E%E5%BD%92-%E8%81%9A%E7%B1%BB-%E9%99%8D%E7%BB%B4/"/>
<url>/2022/03/07/%E5%88%86%E7%B1%BB-%E5%9B%9E%E5%BD%92-%E8%81%9A%E7%B1%BB-%E9%99%8D%E7%BB%B4/</url>
<content type="html"><![CDATA[<blockquote><p>笔记摘录自bilibili网课数据挖掘</p></blockquote><h1 id="分类,回归,聚类,降维"><a href="#分类,回归,聚类,降维" class="headerlink" title="分类,回归,聚类,降维"></a>分类,回归,聚类,降维</h1><h2 id="分类-Classify"><a href="#分类-Classify" class="headerlink" title="分类 Classify"></a>分类 Classify</h2><p>分类可以看作是机器学习中的有监督学习(supervised learning)</p><blockquote><p>有监督学习:是指数据是有标记,可以量化的。针对日常生活中的某一个个体的相关数据,通过数据标签可以量化出一个专属于这个个体的特性类别,我们称这样的类别是标签(lable/target),是有监督学习的体现。</p></blockquote><p>一个最经典的例子:<strong>性别预测问题</strong>,这是一个典型的分类问题。针对每一个人,我们可以根据他的外表数据,行为数据,来推断出这个人是男性还是女性。我们之所以可以随机的看一个人就可以立刻辨别出他(她)的性别,是因为一些性别的专属特征已经固化在我们脑海中。</p><p>有关人的特征数据(例如身高,体重,相关行为)我们用一个向量组来表示,组中元素被称为<strong>特征元素</strong>,例如[身高(height),体重(weight),相关行为(behavior)],我们称这是一个<strong>3维数据</strong>。</p><p>如何体现监督行为?在每一组特征元素向量数据$X$最后,会有一个特征标记$Y$,被称作标签(lable/target),是对当前向量组中数据元素的总结,如果没有这个特征标记则体现为<strong>无监督学习</strong>。</p><p>有监督学习的基本向量组的表达方式为</p><h3 id="分类的向量组和数据矩阵"><a href="#分类的向量组和数据矩阵" class="headerlink" title="分类的向量组和数据矩阵"></a>分类的向量组和数据矩阵</h3><p>$$[data \mid label]$$</p><p>假设整个数据组中存在$N$个人,每个人具有$P$个特征元素,则我们可以得到一个$N \times P$ 数据矩阵,其中$N$为个数,$P$为特征数。数据元素统一用$X$来表示,label则用$Y$来表示。</p><img src="/2022/03/07/%E5%88%86%E7%B1%BB-%E5%9B%9E%E5%BD%92-%E8%81%9A%E7%B1%BB-%E9%99%8D%E7%BB%B4/1.jpeg" class=""><blockquote><p><strong>图片勘误</strong>:最下方角标应该是$P \mid Y$,而不是$P$,$P$只表示竖线左侧的数据元素而不表示标签。</p></blockquote><h3 id="分类的模型训练过程"><a href="#分类的模型训练过程" class="headerlink" title="分类的模型训练过程"></a>分类的模型训练过程</h3><p>首先我们通过已知的1特征数据矩阵(包括特征元素和target标签)来训练模型,今儿对没有label的全新的数据元素(dew data)向量组进行标记,得出label。并且尽可能保证推断出的label标记和真实情况的label保持一致。准确性(accuracy)越高,说明模型训练得越好。</p><img src="/2022/03/07/%E5%88%86%E7%B1%BB-%E5%9B%9E%E5%BD%92-%E8%81%9A%E7%B1%BB-%E9%99%8D%E7%BB%B4/2.jpeg" class=""><p>新模型中的数据维度可能与原数据不相同,虽然模型过程是数据矩阵的形式,但是本质上是对每一个数据元素向量组的推断,通过已有模型得出target label。</p><h2 id="回归-Regression"><a href="#回归-Regression" class="headerlink" title="回归 Regression"></a>回归 Regression</h2><p>回归是我们最早接触的一种数据化类类型,例如我们初中就接触过的线性关系:探寻身高与体重的关系等等。</p><p>分类和回归因为目标不同,所以导致最后的label也不是一致的。分类重在对以后数据进行模型训练,进而对新的没有进行分类的数据进行推断,得出新数据的label。而回归重在对原始数据的内在联系进行分析。对于给定的特性元素向量组和标签label,通过回归来找到内在关系。</p><h3 id="基本回归变量类型"><a href="#基本回归变量类型" class="headerlink" title="基本回归变量类型"></a>基本回归变量类型</h3><ul><li>数值型变量 numerical data</li><li>类别型变量 categorical data<ul><li>二分类变量 binary data</li></ul></li></ul><blockquote><p>数值型变量和类别型变量的最明显区别:数值型变量可以进行比较(comparable),类别型变量不能比较(uncomparable)在类别型变量中讨论最多的就是二分类变量</p></blockquote><p>$$Y = \alpha x_{1} + \beta x_{2} + … +\gamma x_{n}$$</p><p>其实就是我们常见的模型关系,上述公式表述的是数据型变量的关系,而类别型变量就是将具有某一特性类别集合的特征向量组聚合起来,找出共性关系。</p><p>写成数据矩阵的形式如下图:</p><img src="/2022/03/07/%E5%88%86%E7%B1%BB-%E5%9B%9E%E5%BD%92-%E8%81%9A%E7%B1%BB-%E9%99%8D%E7%BB%B4/3.jpeg" class=""><h2 id="聚类-Clustering"><a href="#聚类-Clustering" class="headerlink" title="聚类 Clustering"></a>聚类 Clustering</h2><p>聚类是无监督学习(unsupervised learning)的代表,即数据无标注(没有label)。</p><p>聚类是针对于数据本身进行的划分,相当于做了一个<strong>特征工程</strong>。其目的本质上就是为了让数据变得更“好看一点”,数据聚合可以<strong>让组内数据更加紧密,让组间数据差异尽可能更大</strong>。诸如聚类的无监督学习其实是作为有监督学习的辅助,让有监督学习可以更好地执行。</p><h2 id="聚类模型训练过程"><a href="#聚类模型训练过程" class="headerlink" title="聚类模型训练过程"></a>聚类模型训练过程</h2><p>针对一个没有label的数据矩阵,对该矩阵进行标记,即使用一个已经进行过聚类的数据组来训练模型,然后让一组新的,没有进行聚类的数据进行聚类划分。得到一个一个的特征集群。</p><img src="/2022/03/07/%E5%88%86%E7%B1%BB-%E5%9B%9E%E5%BD%92-%E8%81%9A%E7%B1%BB-%E9%99%8D%E7%BB%B4/4.jpeg" class=""><p>其中$X$为特征向量,$N$为组数,$P$为特征元素,可以很明显看出来聚类后特征元素被区分成不同的组(特征类群)。</p><h2 id="降维-Dimension-Reduction"><a href="#降维-Dimension-Reduction" class="headerlink" title="降维 Dimension Reduction"></a>降维 Dimension Reduction</h2><img src="/2022/03/07/%E5%88%86%E7%B1%BB-%E5%9B%9E%E5%BD%92-%E8%81%9A%E7%B1%BB-%E9%99%8D%E7%BB%B4/5.jpeg" class=""><p>降维也是无监督学习的一种,通过减少冗余特征元素的方式实现对数据的优化,一般情况下,降维之后的特征元素维度要低于降维之前,即$P > P^{`}$</p><ul><li>数据相关信息可能会丢失</li><li>降维可以减少数据噪声</li><li>降维可以对数据进行清洗,让脏数据变干净</li></ul><h3 id="高维度数据和低维度数据"><a href="#高维度数据和低维度数据" class="headerlink" title="高维度数据和低维度数据"></a>高维度数据和低维度数据</h3><ul><li>高维数据 High-demensional Data</li><li>低维数据 Low-dimensional Data</li></ul><blockquote><p>如何判断一个数据矩阵是高维数据矩阵还是低维数据矩阵?<br>如果在一个数据矩阵中,如果$P > N$,则我们认为这个数据矩阵一般是高维度的,因为这样的数据矩阵在多元线性回归中并不能拟合出相关线性。</p></blockquote><p>其实一般认为如果$N$约等于$P$也被算作高维度数据矩阵,具体要看模型效果,并不是绝对的。还有一种特殊情况,如果说在数据特征向量组中,有一组数据响亮可以通过另一组数据向量演化过来的。这样的数据被称为多重多样性,我们也认为这是高维度数据。</p>]]></content>
<categories>
<category> 数据挖掘 </category>
</categories>
<tags>
<tag> 笔记 </tag>
<tag> 机器学习 </tag>
<tag> 数据挖掘 </tag>
</tags>
</entry>
<entry>
<title>Java内部类</title>
<link href="/2022/02/23/Java%E5%86%85%E9%83%A8%E7%B1%BB/"/>
<url>/2022/02/23/Java%E5%86%85%E9%83%A8%E7%B1%BB/</url>
<content type="html"><![CDATA[<h1 id="内部类"><a href="#内部类" class="headerlink" title="内部类"></a>内部类</h1><p>内部类是一类<strong>特殊的类</strong>,指的是定义在一个类的内部的类。实际开发中,为了方便的使<br>用外部类的相关属性和方法,这时候我们通常会定义一个内部类。</p><img src="/2022/02/22/Java%E5%86%85%E9%83%A8%E7%B1%BB/1.png" class=""><p>上图所示,内部类共分为:<strong>匿名内部类</strong>,<strong>局部内部类</strong>和<strong>成员内部类</strong>。而成员内部类又可以分成<strong>非静态内部类</strong>和<strong>静态内部类</strong>。</p><hr><h2 id="内部类的概念"><a href="#内部类的概念" class="headerlink" title="内部类的概念"></a>内部类的概念</h2><p>一般情况,我们把类定义成独立的单元。有些情况下,我们把一个类放在另一个类的内<br>部定义,称为内部类(innerclasses)。内部类可以使用public、default、protected 、private 以及static 修饰。而外部顶级类(我们以前接触的类)只能使用public 和default 修饰。</p><p><strong>==注意!!==</strong></p><p>内部类只是一个编译时概念,一旦我们编译成功,就会成为完全不同的两个类。对于一个名为Outer 的外部类和其内部定义的名为Inner 的内部类。编译完成后会出现==Outer.class== 和==Outer$Inner.class== 两个类的字节码文件。所以内部类是<strong>相对独立</strong>的一种存在,其成员变量/方法名可以和外部类的相同。</p><hr><h2 id="内部类的展示"><a href="#内部类的展示" class="headerlink" title="内部类的展示"></a>内部类的展示</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**内部类Outer*/</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Outer</span> {</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> <span class="type">int</span> <span class="variable">age</span> <span class="operator">=</span> <span class="number">100</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">show</span><span class="params">()</span></span><br><span class="line"> {</span><br><span class="line"> System.out.println(<span class="string">"这是外部类!"</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> {</span><br><span class="line"> Outer.<span class="type">Inner</span> <span class="variable">newname</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Outer</span>().<span class="keyword">new</span> <span class="title class_">Inner</span>();</span><br><span class="line"> newname.inner();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"><span class="comment">/**内部类Inner*/</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Inner</span>{</span><br><span class="line"> <span class="keyword">private</span> <span class="type">int</span> <span class="variable">age</span> <span class="operator">=</span> <span class="number">110000</span>;</span><br><span class="line"><span class="comment">//内部类中可以声明与外部类同名的属性与方法</span></span><br><span class="line"><span class="comment">//非静态方法可以调用静态成员或者方法</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">inner</span><span class="params">()</span>{</span><br><span class="line"> System.out.println(age); <span class="comment">//110000</span></span><br><span class="line"> System.out.println(Test000.<span class="built_in">this</span>.age); <span class="comment">//100</span></span><br><span class="line"> show(); <span class="comment">//这是外部类!</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><blockquote><p><strong>内部类的作用:</strong><br>内部类提供了更好的封装。只能让外部类直接访问,不允许同一个包中的其他类直接访问。<br>内部类可以直接访问外部类的私有属性,内部类被当成其外部类的成员。但外部类不能访问内部类的内部属性。</p></blockquote><hr><h2 id="非静态内部类"><a href="#非静态内部类" class="headerlink" title="非静态内部类"></a>非静态内部类</h2><p><strong>非静态内部类(外部类里使用非静态内部类和平时使用其他类没什么不同)</strong></p><ul><li><p>非静态内部类对象必须寄存在一个<strong>外部类对象</strong>里。因此,如果有一个非静态内部类对象那么一定存在对应的外部类对象。非静态内部类对象单独属于<strong>外部类的某个对象</strong>。</p></li><li><p>非静态内部类可以直接访问外部类的成员,但是外部类不能直接访问非静态内部类成员。</p></li><li><p>非静态内部类不能有静态方法、静态属性和静态初始化块。</p></li><li><p>成员变量访问要点:(例子同上面代码)</p><ol><li>内部类里方法的局部变量:变量名。</li><li>内部类属性:this.变量名。</li><li>外部类属性:外部类名.this.变量名。</li></ol></li></ul><h3 id="非静态内部类对象创建方式"><a href="#非静态内部类对象创建方式" class="headerlink" title="非静态内部类对象创建方式"></a>非静态内部类对象创建方式</h3><p><strong>非静态内部类对象新建方式一共有两种:</strong>(针对Outer类内嵌Inner类举例)</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//第一种方式</span></span><br><span class="line">Outer.<span class="type">Inner</span> <span class="variable">in01</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Outer</span>().<span class="keyword">new</span> <span class="title class_">Inner</span>(); <span class="comment">//此时in01作为内部类的对象可以实现方法或者成员调用</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//第二种方式</span></span><br><span class="line"><span class="type">Outer</span> <span class="variable">out02</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Outer</span>();</span><br><span class="line"><span class="type">Inner</span> <span class="variable">in02</span> <span class="operator">=</span> out02.<span class="keyword">new</span> <span class="title class_">Inner</span>(); <span class="comment">//此时in02作为内部类的对象可以实现方法或者成员调用</span></span><br></pre></td></tr></table></figure><hr><h2 id="静态内部类"><a href="#静态内部类" class="headerlink" title="静态内部类"></a>静态内部类</h2><p>与大多数静态方法相似,静态内部类只需要在类名前加上static即可</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">static</span> <span class="keyword">class</span> <span class="title class_">ClassName</span></span><br><span class="line">{</span><br><span class="line"><span class="comment">//类体</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>静态内部类可以访问外部类的静态成员,不能访问外部类的普通成员。</li><li>静态内部类看做外部类的一个静态成员。<br>(这点与静态方法不能调用非静态成员性质一致)</li></ul><h3 id="静态内部类对象创建方式"><a href="#静态内部类对象创建方式" class="headerlink" title="静态内部类对象创建方式"></a>静态内部类对象创建方式</h3><p>依旧针对Outer类内嵌Inner类举例:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//通过new 外部类名.内部类名() 来创建内部类对象</span></span><br><span class="line">Outer.<span class="type">Inner</span> <span class="variable">in03</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Outer</span>.Inner();</span><br><span class="line"></span><br><span class="line">-----------------------------------------------</span><br><span class="line"><span class="comment">//一些举例</span></span><br><span class="line">Class Outer{</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="type">int</span> <span class="variable">a</span> <span class="operator">=</span> <span class="number">100</span>;</span><br><span class="line"><span class="keyword">public</span> <span class="type">int</span> <span class="variable">b</span> <span class="operator">=</span> <span class="number">200</span>;</span><br><span class="line"><span class="keyword">static</span> <span class="keyword">class</span> <span class="title class_">Inner</span>{</span><br><span class="line">puiblic <span class="keyword">void</span> <span class="title function_">print</span><span class="params">()</span>{ <span class="comment">//静态内部类方法即便前面没有加static修饰也会被定义为静态方法</span></span><br><span class="line">System.out.println(a); <span class="comment">//可以正常输出100</span></span><br><span class="line">System.out.println(b); <span class="comment">//静态方法不能调用非静态属性,这行代码会报错</span></span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr><h2 id="匿名内部类"><a href="#匿名内部类" class="headerlink" title="匿名内部类"></a>匿名内部类</h2><p>Java 中可以实现一个类中包含另外一个类,且不需要提供任何的类名直接实例化。主要是用于在我们需要的时候创建一个对象来执行特定的任务,可以使代码更加简洁。匿名类是不能有名字的类,它们不能被引用,只能在创建时用 new 语句来声明它们。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//语法体</span></span><br><span class="line"><span class="keyword">new</span> 父类构造器(实参类表) \实现接口() </span><br><span class="line">{</span><br><span class="line"><span class="comment">//匿名内部类类体!</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>匿名内部类的应用主要有两种:一种是<strong>匿名类继承父类</strong>、另一种是<strong>匿名类实现接口</strong>。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//匿名类继承父类</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//一个定义类</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Polygon</span> { </span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">display</span><span class="params">()</span> {</span><br><span class="line"> System.out.println(<span class="string">"在 Polygon 类内部。"</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">AnonymousDemo</span> {</span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">createClass</span><span class="params">()</span> {</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 创建的匿名类继承了 Polygon 类</span></span><br><span class="line"> <span class="type">Polygon</span> <span class="variable">p1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Polygon</span>() {</span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">display</span><span class="params">()</span> {</span><br><span class="line"> System.out.println(<span class="string">"在匿名类内部。"</span>);</span><br><span class="line"> }</span><br><span class="line"> };</span><br><span class="line"> p1.display();</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="comment">//实例中,创建了 Polygon 类,该类只有一个方法 display(),AnonymousDemo 类继承了 </span></span><br><span class="line"><span class="comment">//Polygon 类并重写Polygon 类的 display() 方法</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Main</span> {</span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> {</span><br><span class="line"> <span class="type">AnonymousDemo</span> <span class="variable">an</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">AnonymousDemo</span>();</span><br><span class="line"> an.createClass();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>上述代码中,AnonymousDemo匿名类中的createClass()方法内部继承类新建了一个Polygon对象并改写Override了display()方法,这中间的p1对象调用并销毁次数与方法调用次数一致。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//匿名类实现接口</span></span><br><span class="line"><span class="comment">//首先定义一个接口</span></span><br><span class="line"><span class="keyword">interface</span> <span class="title class_">Inter</span>{</span><br><span class="line"><span class="keyword">void</span> <span class="title function_">run</span><span class="params">()</span>; <span class="comment">//内部只有一个run()方法</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//再定义一个实现,这是一个有名字的类,是可以反复调用新建对象的 </span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Imp</span> <span class="keyword">implements</span> <span class="title class_">Inter</span>{</span><br><span class="line"></span><br><span class="line"><span class="meta">@override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">run</span><span class="params">()</span>{</span><br><span class="line">System.out.println(<span class="string">"我正在跑!"</span>);</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//然后定义public主类</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">AnonymousInnerClass</span>{</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test</span><span class="params">(Inter a)</span></span><br><span class="line">{</span><br><span class="line">a.run(); <span class="comment">//方法的定义</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span></span><br><span class="line">{</span><br><span class="line"><span class="type">AnonymousInnerClass</span> <span class="variable">b</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">AnonymousInnerClass</span>(); <span class="comment">//创建对象</span></span><br><span class="line"><span class="comment">// b.test(); //!!括号内需要传参</span></span><br><span class="line"><span class="comment">//一般情况下,我们可以通过implements实现接口,这里我我们采用匿名类;</span></span><br><span class="line">b.test(<span class="keyword">new</span> <span class="title class_">Imp</span>); <span class="comment">//可以通过定义的实现完成接口,输出结果为 我正在跑!</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//此外,可以通过定义匿名类来实现接口</span></span><br><span class="line"></span><br><span class="line">b.test(<span class="keyword">new</span> <span class="title class_">Inter</span>(){ <span class="comment">//没有实际名字的类</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">run</span><span class="params">()</span>{</span><br><span class="line">System.out.println(<span class="string">"我正在慢跑五分钟!"</span>);</span><br><span class="line">}</span><br><span class="line">}); <span class="comment">//定义和调用同时进行,调用结束,这个类直接被销毁</span></span><br><span class="line"><span class="comment">//每一次调用,这个方法只能调用一次,每一次都是新的</span></span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr><h2 id="局部内部类"><a href="#局部内部类" class="headerlink" title="局部内部类"></a>局部内部类</h2><p>定义在方法内部的,作用域只限于本方法,称为局部内部类。</p><p>局部内部类的的使用主要是用来解决比较复杂的问题,想创建一个类来辅助我们的解决<br>方案,到那时又不希望这个类是公共可用的,所以就产生了局部内部类。局部内部类和成员<br>内部类一样被编译,只是它的作用域发生了改变,它只能在该方法中被使用,出了该方法就<br>会失效。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 测试局部内部类</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">TestLocalInnerClass</span> {</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">show</span><span class="params">()</span> {</span><br><span class="line"><span class="comment">//作用域仅限于该方法</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Inner</span> {</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test</span><span class="params">()</span> {</span><br><span class="line">System.out.println(<span class="string">"Hello World"</span>);</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Inner</span>().test(); <span class="comment">//调用结束就销毁</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[ ] args)</span> {</span><br><span class="line"><span class="keyword">new</span> <span class="title class_">TestLocalInnerClass</span>().show();</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> Java </category>
</categories>
<tags>
<tag> Java </tag>
</tags>
</entry>
<entry>
<title>Comparable接口的实现与使用</title>
<link href="/2022/02/23/Comparable%E6%8E%A5%E5%8F%A3%E7%9A%84%E5%AE%9E%E7%8E%B0%E4%B8%8E%E4%BD%BF%E7%94%A8/"/>
<url>/2022/02/23/Comparable%E6%8E%A5%E5%8F%A3%E7%9A%84%E5%AE%9E%E7%8E%B0%E4%B8%8E%E4%BD%BF%E7%94%A8/</url>
<content type="html"><![CDATA[<h1 id="1-Comparable接口声明及其作用"><a href="#1-Comparable接口声明及其作用" class="headerlink" title="1. Comparable接口声明及其作用"></a>1. Comparable接口声明及其作用</h1><p>想对某个类的对象之间做比较,就需要实现Comparable 接口。接口中只有一个方法compareTo,这个方法定义了对象之间的比较规则。依据这个“比较规则”,我们就能对所有对象实现排序。</p><p>下面是Comparable接口的声明以及作用,可以看到它可以使继承他的类进行比较大小,只需要调用实现类的compareTo方法即可</p><blockquote><p>public interface Comparable < T ><br>This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class’s natural ordering, and the class’s compareTo method is referred to as its natural comparison method.<br>此接口对实现它的每个类的对象施加总顺序。这种排序称为类的自然排序,而类的compareTo方法称为其自然比较方法。</p></blockquote><p>实际上,java 中排序算法的底层也依赖Comparable接口,Comparable接口中只有一个方法:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="type">int</span> <span class="title function_">compareTo</span><span class="params">(Object obj)</span> \\其中 obj 为要比较的对象</span><br></pre></td></tr></table></figure><p>实现了Comparable接口的类,可以很好的和集合类或是一些泛型算法很好的协作,你可以付出很小的代价实现强大的功能。</p><h1 id="2-实例"><a href="#2-实例" class="headerlink" title="2. 实例"></a>2. 实例</h1><p>compareTo()方法传入该类的另外一个实例,返回一个int值,这个方法每执行一次都是对传入的对象和和本生对象进行比较。<strong>返回的int值如果是一个正值(不包括零)则在数组或是集合中交换两个实例的位置,否则位置保持不变。</strong></p><p>在Arrays包中调用sort方法时,通过实现Comparable接口的实现类可以override <strong>compareTo()</strong> 方法来实现具体情况下的比较。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> cn.jkwzs;</span><br><span class="line"><span class="keyword">import</span> java.util.Arrays; <span class="comment">//调用包</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">CompareTo</span> {</span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> {</span><br><span class="line"> Man[ ] msMans = { <span class="keyword">new</span> <span class="title class_">Man</span>(<span class="number">3</span>, <span class="string">"a"</span>), <span class="keyword">new</span> <span class="title class_">Man</span>(<span class="number">60</span>, <span class="string">"b"</span>), <span class="keyword">new</span> <span class="title class_">Man</span>(<span class="number">2</span>, <span class="string">"c"</span>) };</span><br><span class="line"> Arrays.sort(msMans); <span class="comment">//调用compareTo()方法</span></span><br><span class="line"> System.out.println(Arrays.toString(msMans));</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Man</span> <span class="keyword">implements</span> <span class="title class_">Comparable</span> { <span class="comment">//实现接口</span></span><br><span class="line"> <span class="type">int</span> age;</span><br><span class="line"> String name;</span><br><span class="line"> <span class="keyword">public</span> <span class="title function_">Man</span><span class="params">(<span class="type">int</span> age, String name)</span> { <span class="comment">//构造器</span></span><br><span class="line"> <span class="built_in">super</span>();<span class="built_in">this</span>.age = age;</span><br><span class="line"> <span class="built_in">this</span>.name = name;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">public</span> String <span class="title function_">toString</span><span class="params">()</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">this</span>.name+<span class="string">":"</span>+<span class="built_in">this</span>.age;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">compareTo</span><span class="params">(Object o)</span> { <span class="comment">//重写compareTo()方法</span></span><br><span class="line"> <span class="type">Man</span> <span class="variable">man</span> <span class="operator">=</span> (Man) o;</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">this</span>.age < man.age) {</span><br><span class="line"> <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">this</span>.age > man.age) {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><img src="/2022/02/22/Comparable%E6%8E%A5%E5%8F%A3%E7%9A%84%E5%AE%9E%E7%8E%B0%E4%B8%8E%E4%BD%BF%E7%94%A8/1.png" class=""><p>实现结果为:</p><blockquote><p>[c:2, a:3, b:60]</p></blockquote>]]></content>
<categories>
<category> Java </category>
</categories>
<tags>
<tag> Java </tag>
</tags>
</entry>
<entry>
<title>static静态属性声明和赋值问题</title>
<link href="/2022/02/23/static%E9%9D%99%E6%80%81%E5%B1%9E%E6%80%A7%E5%A3%B0%E6%98%8E%E5%92%8C%E8%B5%8B%E5%80%BC%E9%97%AE%E9%A2%98/"/>
<url>/2022/02/23/static%E9%9D%99%E6%80%81%E5%B1%9E%E6%80%A7%E5%A3%B0%E6%98%8E%E5%92%8C%E8%B5%8B%E5%80%BC%E9%97%AE%E9%A2%98/</url>
<content type="html"><![CDATA[<p>直接放结论,变量一定是<strong>先声明再赋值</strong>,无论是针对<strong>普通属性</strong>还是<strong>静态属性</strong>。</p><p>一个最简单的例子:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1314</span>;</span><br></pre></td></tr></table></figure><p>在JVM虚拟机中实现的时候,是先声明变量属性 “i” 的存在,然后为它赋值1314。</p><p>我们再来写一个简单的含静态属性的类并声明两个对象:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">StuDent</span>{</span><br><span class="line"> String name;</span><br><span class="line"> <span class="keyword">static</span> <span class="type">int</span> age;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> String <span class="title function_">getname</span><span class="params">()</span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">this</span>.name;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">Static</span><span class="params">()</span>{</span><br><span class="line"> System.out.println(<span class="string">"一个静态方法"</span>);</span><br><span class="line"> System.out.println(age);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">StuDent</span> <span class="variable">s1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StuDent</span>();</span><br><span class="line"><span class="type">StuDent</span> <span class="variable">s2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StuDent</span>();</span><br></pre></td></tr></table></figure><p>其中对象的静态属性的分布在内存中应该是如下图所示:</p><img src="/2022/02/22/static%E9%9D%99%E6%80%81%E5%B1%9E%E6%80%A7%E5%A3%B0%E6%98%8E%E5%92%8C%E8%B5%8B%E5%80%BC%E9%97%AE%E9%A2%98/1.png" class=""><p>静态变量是在类初始化时是<strong>最先被加载</strong>的,JVM会去查找类中<strong>所有的静态声明</strong>,然后<strong>分配空间</strong>,这时候只是完成了<strong>地址空间的分配</strong>,还<strong>没有赋值</strong>,之后JVM会根据类中静态赋值(包括静态类赋值和静态块赋值)的<strong>先后顺序</strong>来执行。所以,当一个静态属性的地址被声明之后,它的内存地址的确定的,仅按照<strong>最后一次静态代码块的赋值</strong>来确定最终赋值。</p><p>下面再来举几个比较具体的例子:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">static</span>{</span><br><span class="line"> i = <span class="number">100</span>;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="type">int</span> <span class="variable">m</span> <span class="operator">=</span> <span class="number">200</span>;</span><br><span class="line"><span class="keyword">static</span>{</span><br><span class="line"> m = <span class="number">100</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>main函数中输出i和m的值代码结果为1和100。所以我们可以很清晰地看出来,确实是按照最后一次静态代码块的赋值来确定最终值。此外,由于JVM会首先查找类中的所有静态声明,所以即便是在第一个代码块中没有首先声明int变量属性i而是直接赋值,也不会报错,之后才是对它的具体赋值。</p>]]></content>
<categories>
<category> Java </category>
</categories>
<tags>
<tag> Java </tag>
</tags>
</entry>
<entry>
<title>Vue3背景认识和面试点</title>
<link href="/2022/02/22/Vue3%E8%83%8C%E6%99%AF%E8%AE%A4%E8%AF%86%E5%92%8C%E9%9D%A2%E8%AF%95%E7%82%B9/"/>
<url>/2022/02/22/Vue3%E8%83%8C%E6%99%AF%E8%AE%A4%E8%AF%86%E5%92%8C%E9%9D%A2%E8%AF%95%E7%82%B9/</url>
<content type="html"><![CDATA[<h1 id="Web前端技术发展"><a href="#Web前端技术发展" class="headerlink" title="Web前端技术发展"></a>Web前端技术发展</h1><p>早期的Web应用主要是以静态页面的浏览(比如新闻浏览),这些静态页面使用HTML语音编写。1995 年,Netseape 公司的工程师 Brendan Eich 设计了JavaScript 脚本语言,使前端网页具有动态的效果(跑马灯,浮动广告等),以及与用户交互能力的表单。</p><p>然而随着互联网的发展,很多的线下业务的开始向向上发展。基于 Internet 的 Web 应用也变越复杂,用户所访詞的资源已不仅仅局限于服务器硬盘上存放的静态网页,更多的应用需要根据户的请求动态生成页面信息,复杂一些的还需要从数据库中查询数据,经过一定的运算,生成一个页面返回给用户。</p><ul><li>1996 年,微软公司推出了 ASP 技术;</li><li>1997年,Sun 公司推出了 JSP技术;</li><li>1998年6月,PHP 3 正式发布</li></ul><p>由此网页开启了真正动态交互的阶段。这些服务器端的动态页面技术是的网页可以获取服务器的数据信息并保持更新,推动了以 Google 为代表的搜索引擎和各种论坛的出现,Web 开始快速发展。服务器端网页动态交互功能不断丰富,伴随的是后端逻辑复杂度的快速上升以及及代码越来越复杂。为了更好地管理后端逻辑,出现了大量后端的 MVC 框架。</p><p>动态页面实现了动态交互和数据即时存和取,当由于动态页面是由后端技术驱动的,每一次的数据交互都需要刷新一次浏览器,频繁的页面刷新非常影响用户的体验,这个问题直到Goole公司在2004年使用Ajax技术开发的Gmail和GoogleMaps的发布后才得到解决。</p><h2 id="Ajax"><a href="#Ajax" class="headerlink" title="Ajax"></a>Ajax</h2><p>Ajax改变了传统的用户请求——等待——响应这种web的交互模式,采用异步交互机制避免了用户对服务器响应的等待。提供了更好的用户体验,此外,它还改变了用户请求—服务器响应—-页面刷新的用户体验方式,提供了页面局部刷新数的实现机制,Ajax开启了Web2.0时代。</p><p>由于Ajax的火热,也带动了一些古老技术的复兴,css和javascript这两个原先被程序员瞧不上的技术收到了前所未有的关注,而这一切都源于Ajax带来的全新的用户体验。</p><blockquote><p>Ajax全称是:<strong>Asynchronous Javascript And Xml</strong> 即异步<strong>Javascript</strong>和<strong>XML</strong>。<br>Ajax最早是由Adaptive Path公司的咨询顾问Jese James Garrett于2005年提出的。Garrett专门写了一篇文章来讲述Ajax这一新的Web开发方式。Ajax为用户带来了更好的用户体验,在传统的web应用程序中,用户向服务器发送一个请求,然后等待,服务器对应请求进行处理,然后返回一个响应,这是一种同步的处理方式,如果服务器处理请求的时间比较长,那么用户将不得不长时间的等待。在后台执行程序的过程中,如果执行的程序出现异常还可能导致某个业务的执行出错会影响整个的体验。</p></blockquote><h3 id="同步请求和异步请求的利弊,为什么同步请求不总是可行"><a href="#同步请求和异步请求的利弊,为什么同步请求不总是可行" class="headerlink" title="同步请求和异步请求的利弊,为什么同步请求不总是可行"></a>同步请求和异步请求的利弊,为什么同步请求不总是可行</h3><p>传统的页面应用中,当一个请求进来,服务器开始进行动态渲染,把数据作用域放到数据模型中,然后再跳转到视图层,然后在用户端页面上用诸如JSP等语法替换,来实现动态化 。动态化的覆盖本质上就是将查询到的数据使用动态语言来实现渲染,但是这种情况很消耗服务器资源流量。网页访问的总时长就是所有方法调用的单个时长的汇总,如果说在方法执行的过程中有一个数据的查询消耗了过多的服务器资源和时间,由于JAVA语法的执行时串行执行,在这个方法调用之后的所有方法都需要等待这个方法调用完毕之后再去执行,这个时间过长势必会影响用户体验;此外,如果在方法执行过程用有一个报错,那么服务器直接抛出异常,跳转错误页面。</p><p>而Ajax可以提前先把页面的html,css渲染出来,等页面加载完毕之后,再用事件的方式到服务器端偷偷请求,再把数据请求回来加载在页面上。这就是异步思想就不会出现因为某一个报错或者消耗时间过长来影响我的加载速度或者页面渲染。异步请求本质上是一种局部刷新。如果存在后一个方法接口没有加载出来也仅仅是会影响当前区域的加载,不糊影响到整体布局。</p><img src="/2022/02/22/Vue3%E8%83%8C%E6%99%AF%E8%AE%A4%E8%AF%86%E5%92%8C%E9%9D%A2%E8%AF%95%E7%82%B9/1.png" class=""><p>req和resp只会从服务器请求出来页面的基本样式(html,css),而数据则是通过Ajax异步的方式去偷偷请求,这样会在最大程度上提高服务器的吞吐量,而且每一个线程间互不影响。</p><h3 id="为什么ajax服务器端早期返回的是xml,现在是json呢?"><a href="#为什么ajax服务器端早期返回的是xml,现在是json呢?" class="headerlink" title="为什么ajax服务器端早期返回的是xml,现在是json呢?"></a>为什么ajax服务器端早期返回的是xml,现在是json呢?</h3><p>不论我们通过ajax还是正常的请求/响应,其目的都是为了获取服务器的数据,渲染页面。</p><p>正常的请求和响应,每种语音都有在服务器端渲染的方式,比如:jsp + 标签/el表达式。这是一种服务器端渲染方式。都是一种语言,都是自家人,解析认识的。</p><p>异步请求服务端:服务端给予客户端什么样数据格式就是命题了?———-javascript——jsp/php/asp(例子:把一个java对象返还给js,肯定不会被识别)</p><p>如果用字符串自己拼接返回,可能会你分隔符会和具体内容冲突就不适合,例如“#,*”等比较常见的分隔符号,如果说系统或者用户数据中存在同类型的特殊字符,则会影响到数据分割。</p><p>所以早期的ajax异步处理是通过xml字符串进行传输,然后js有domxml对象可以对xml进行解析获取每个点的值,然后进行渲染。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">User</span> <span class="variable">user</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">User</span>();</span><br><span class="line">user.setId(<span class="number">1</span>);</span><br><span class="line">user.setName(<span class="string">"yykk"</span>);</span><br><span class="line"></span><br><span class="line"><span class="type">String</span> <span class="variable">str</span> <span class="operator">=</span> <span class="string">"<id>1</id><name>yykk</name>"</span>; <span class="comment">//js--domxml</span></span><br></pre></td></tr></table></figure><p>进几年来,后面xml笔记的笨重。节点过多,层级过深,解析也一个很大的问题,所以新的数据格式应运而生:json。</p><p>从这里要明白一个道理:xml也好还是json也好,都是一种有格式的<strong>字符串</strong>,方便你解析和获取,仅此而已。浏览器和服务器的数据交互方式永远是字符串形式。</p><h1 id="MVC,MVP-和-MVVM"><a href="#MVC,MVP-和-MVVM" class="headerlink" title="MVC,MVP 和 MVVM"></a>MVC,MVP 和 MVVM</h1><h2 id="MVC"><a href="#MVC" class="headerlink" title="MVC"></a>MVC</h2><p><strong>MVC</strong>是从Web开发中应用非常广泛的一种框架模式,之后又演变出了MVP模式和MVVM模式。</p><p>在 MVC 模式中,一个应用被分成三个部分,即模型(Model)、视图(View)和控制器(Controller)。</p><blockquote><p><strong>什么是MVC?</strong><br>MVC(Model-View-Controller)即模型-视图-控制层,MVC框架有助于将应用程序分割成若干逻辑部件,使程序设计变得更加容易。MVC框架提供了一种按功能对各种对象进行分割的方法,其目的:将各对象间的耦合程度降到最低,</p></blockquote><p><strong>模型</strong>:代表应用程序的数据以及用于访问控制和修改这些数据的业务规则。当模型发生改变时,它会通知视图,并为视图提供查询模型相关状态的能力。同时,它也为控制器提供访问封装在模型内部的应用程序功能的能力。</p><p><strong>视图</strong>:用来组织模型的内容。它从模型获得数据并指定这些数据如何表现。当模型变化时,视图负责维护数据表现的一致性。视图同时将用户的请求通知控制器。</p><p><strong>控制器</strong>:定义了应用程序的行为。它负责对来自视图的用户请求进行解释,并把这些请求映射成相应的行为,这些行为由模型负责实现。在独立运行的 GUI客户端,用户的请求可能是一些鼠标单击或菜单选择操作。在一个 Web 应用程序中,它们的表现形式可能是一些来自客户端的 GET 或 POST 的 HTTP 请求。模型所实现的行为包括处理业务和修改模型的状态。根据用户请求和模型行为的结果,控制器选择一个视图作为对用户请求的响应。图 1-1描述了 MVC 模式中模型、视图、</p><p><strong>控制器三部分的关系</strong></p><img src="/2022/02/22/Vue3%E8%83%8C%E6%99%AF%E8%AE%A4%E8%AF%86%E5%92%8C%E9%9D%A2%E8%AF%95%E7%82%B9/2.png" class=""><p>而接下来提到的MVP和MVVM模式,都是由MVC模式演化而来,把数据和模版的渲染从后端转移到前端,从而实现减轻服务器压力的一种模式。</p><h2 id="MVP"><a href="#MVP" class="headerlink" title="MVP"></a>MVP</h2><p>MVP(Model-View-Presenter)是由经典的 MVC 模式演变而来,它们的基本思想有相通的地方:模型(Model)提供数据,视图(View)负责显示,表示器(Presenter)负责逻辑的处理。<br>MVP 与 MVC 最大的区别是:在 MVP 中 View 并不直接使用 Model,它们之间的通信是通过Presenter 进行的,所有的交互都发生在 Presenter 内部,而在 MVC 中 View 会直接从 Model 中读取数据而不是通过 Controller。</p><p>MVP 模式中模型、视图和表示器三者的关系如图所示。</p><img src="/2022/02/22/Vue3%E8%83%8C%E6%99%AF%E8%AE%A4%E8%AF%86%E5%92%8C%E9%9D%A2%E8%AF%95%E7%82%B9/3.png" class=""><h2 id="MVVM"><a href="#MVVM" class="headerlink" title="MVVM"></a>MVVM</h2><p>MVVM(Model-View-ViewModel)是一种软件框架模式(由微软公司的 WPF 和 Sivetighn的架构师 Ken Cooper 和 Ted Peters 开发),也是一种简化用户界面的事件驱动编程方式,由 JohmGossman(微软公司的 WPF 和 Silverlight 的另一架构师)于 2005 年在他的博客上发表。</p><p>MVVM模式的核心是数据驱动,即 ViewModel,ViewModel是 View和Moiel 的关系映射。ViewModel 是一个值转换器(Value Converer),负责转换 Model中的数据对象,使数据变得更加易于管理和使用。在 MVVM 中 View 和Model是不可以直接进行通信的,它们之间存在着ViewModel 这个中介,充当观察者的角色。</p><p>MVVM模式最核心的特征就是 <strong>双向数据绑定</strong>,当用户操作 View时,ViewModel 感知到变化,然后通知Model发生了相应改变。反之,Model发生了改变,ViewModel感知到变化,然后通知View进行更新。ViewModel向上与View进行双向数据绑定,向下与Model通过接口请求进行数据交互,起到承上启下的作用:</p><img src="/2022/02/22/Vue3%E8%83%8C%E6%99%AF%E8%AE%A4%E8%AF%86%E5%92%8C%E9%9D%A2%E8%AF%95%E7%82%B9/4.png" class=""><p>MVVM的核心理念是:通过声明书的数据绑定实现View的分离,完成解耦View。</p><p>最具有代表性的前端框架有:Angular、Vue。</p><h1 id="初识-Vue-js"><a href="#初识-Vue-js" class="headerlink" title="初识 Vue.js"></a>初识 Vue.js</h1><p>Vue是一套基于MVVM模式的用于构建用户界面的Javascript框架。它是以数据驱动和组件化的思想构建的。Vuej是由一个名叫尤雨溪的作者开发的,他于 2013 年12月7 日发布了 Vuejs 的 0.6.0版本(之前的版本不叫 Vue.js),2015年10月26 日发布了 1.0.0 版本,2016 年 10 月1日发布了 2.0.0 版本,2020年 9 月 18日发布了3.0版本代号为 One Pieee。本书内容基于最新发布的 Vue.js 3.0 版本。</p><h2 id="渐进式框架"><a href="#渐进式框架" class="headerlink" title="渐进式框架"></a>渐进式框架</h2><p>Vue 是渐进式的 JavaSeript 框架。所谓渐进式,就是把框架进行分层设计,每层都是可选的。框架的选择取决于你所设计的系统的架构大小。</p><p>最核心的是:声明式渲染,向外是组件系统,在这个基础上再加入前端理由和状态挂你,最外层的构建系统。</p><p>从内到外:声明式渲染,组件系统,前端路由(vue-router),状态管理(vuex),构建系统(vue-cli)</p><ol><li><p>假如你的系统比较简单,更多的是需要访问界面中的DOM节点,以获取用户输入数据或将更新后的数据渲染到视图中,那么可以将Vuejs作用一个javascript库来使用。使用他的声明式渲染机制可以轻松地操作DOM。实现数据变化时的自动视图渲染。</p></li><li><p>如果你前端界面比较复杂,那么可以考虑将界面元素组件化,利用Vuejs的组件化系统将界面元素与业务逻辑包装在为一个个组件。采用分而治之的的策略。不但可以降低前端系统的复杂度,组件本身还可以复用。</p></li><li><p>如果要求将前后端分离,将前端做成单页应用程序,那么可以引入前端理由Vue Router,实现单页应用,如果前端应用中有很多需要在多个组件间共享,如果用户数据,那么可以引入Vuex统一对状态进行管理。</p></li><li><p>Vue提供的构建系统可以轻松地搭建一个脚手架项目,项目内置了运行环境,便于开发,调试并观察程序的运行结果,此外项目也集成了Webpack打包工具。可以很容易地构建发布。</p><h2 id="Vue初始化的规律"><a href="#Vue初始化的规律" class="headerlink" title="Vue初始化的规律"></a>Vue初始化的规律</h2></li></ol><ul><li>初始化是固定格式,Vue.createApp任何一个单词都不能写错,必须完全匹配</li><li>vue3和vue3的改变,初始化发生了改变,data不再是一个对象,而是一个函数+返回对象+生命周期,三者进行融合</li><li>如果页面上的数据需要被替换,那么就必须先到data中定义一个属性</li><li>想尽一切办法然后通过axios或者一些事件去改变这个data的属性,vue就会自动替换view视图</li><li>再替换过程中,可能会用到vue指令和语法</li></ul><h2 id="一个简单的vue了解源码"><a href="#一个简单的vue了解源码" class="headerlink" title="一个简单的vue了解源码"></a>一个简单的vue了解源码</h2><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><!DOCTYPE <span class="keyword">html</span>></span></span><br><span class="line"><span class="tag"><<span class="name">html</span>></span></span><br><span class="line"><span class="tag"><<span class="name">head</span>></span></span><br><span class="line"><span class="tag"><<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">"utf-8"</span> /></span></span><br><span class="line"><span class="tag"><<span class="name">title</span>></span><span class="tag"></<span class="name">title</span>></span></span><br><span class="line"><span class="comment"><!-- <script src="https://unpkg.com/vue@next"></script> --></span></span><br><span class="line"><span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"js/v3.2.8/vue.global.prod.js"</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span> <span class="attr">charset</span>=<span class="string">"utf-8"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"><span class="tag"></<span class="name">head</span>></span></span><br><span class="line"><span class="tag"><<span class="name">body</span>></span></span><br><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"app"</span>></span></span><br><span class="line"><span class="comment"><!-- 渲染data数据模型中的数据到视图中 --></span></span><br><span class="line"><span class="tag"><<span class="name">h1</span>></span>{{title}}<span class="tag"></<span class="name">h1</span>></span></span><br><span class="line"><span class="comment"><!-- 渲染属性 --></span></span><br><span class="line"><span class="tag"><<span class="name">a</span> <span class="attr">v-bind:href</span>=<span class="string">"url"</span> <span class="attr">target</span>=<span class="string">"_blank"</span>></span>个人博客网站<span class="tag"></<span class="name">a</span>></span></span><br><span class="line"><span class="comment"><!-- 渲染html --></span></span><br><span class="line"><span class="tag"><<span class="name">p</span> <span class="attr">v-html</span>=<span class="string">"html"</span>></span><span class="tag"></<span class="name">p</span>></span></span><br><span class="line"><span class="comment"><!-- 事件绑定和处理 --></span></span><br><span class="line"><span class="tag"><<span class="name">button</span> <span class="attr">v-on:click</span>=<span class="string">"clickme"</span>></span>点我<span class="tag"></<span class="name">button</span>></span></span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"><<span class="name">script</span>></span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"><span class="keyword">const</span> vm = <span class="title class_">Vue</span>.<span class="title function_">createApp</span>({</span></span><br><span class="line"><span class="language-javascript"><span class="title function_">data</span>(<span class="params"></span>){ <span class="comment">//数据模型</span></span></span><br><span class="line"><span class="language-javascript"><span class="keyword">return</span>{</span></span><br><span class="line"><span class="language-javascript"><span class="attr">title</span>:<span class="string">"Hello Vue3.x 我来啦!"</span>,</span></span><br><span class="line"><span class="language-javascript"><span class="attr">url</span>:<span class="string">"https://www.jkwzs.cn"</span>,</span></span><br><span class="line"><span class="language-javascript"><span class="attr">html</span>:<span class="string">"<strong>一个大三在读学生</strong>"</span></span></span><br><span class="line"><span class="language-javascript">}</span></span><br><span class="line"><span class="language-javascript">},</span></span><br><span class="line"><span class="language-javascript"><span class="attr">methods</span>:{</span></span><br><span class="line"><span class="language-javascript"><span class="title function_">clickme</span>(<span class="params"></span>){</span></span><br><span class="line"><span class="language-javascript"><span class="title function_">alert</span>(<span class="string">"点击我了"</span>);</span></span><br><span class="line"><span class="language-javascript">}</span></span><br><span class="line"><span class="language-javascript">}</span></span><br><span class="line"><span class="language-javascript">}).<span class="title function_">mount</span>(<span class="string">"#app"</span>) <span class="comment">// 挂载点</span></span></span><br><span class="line"><span class="language-javascript"></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"><span class="tag"></<span class="name">body</span>></span></span><br><span class="line"><span class="tag"></<span class="name">html</span>></span></span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> Vue </category>
</categories>
<tags>
<tag> 笔记 </tag>
<tag> 前端 </tag>
<tag> Vue </tag>
</tags>
</entry>
<entry>
<title>Intro to AI Chapter 3 Uncertainty</title>
<link href="/2022/02/20/Intro-to-AI-Chapter-3-Uncertainty/"/>
<url>/2022/02/20/Intro-to-AI-Chapter-3-Uncertainty/</url>
<content type="html"><![CDATA[<h1 id="Chapter-3-Uncertainty"><a href="#Chapter-3-Uncertainty" class="headerlink" title="Chapter 3 Uncertainty"></a>Chapter 3 Uncertainty</h1><h2 id="Probability"><a href="#Probability" class="headerlink" title="Probability"></a>Probability</h2><p>Uncertainty can be represented as a number of events and the likelihood, or probability, of each of them happening.</p><h3 id="Axioms-in-Probability"><a href="#Axioms-in-Probability" class="headerlink" title="Axioms in Probability"></a>Axioms in Probability</h3><ul><li>0 < $P(ω)$ < 1: every value representing probability must range between 0 and 1.<ul><li>Zero is an impossible event, like rolling a standard die and getting a 7.</li><li>One is an event that is certain to happen, like rolling a standard die and getting a value less than 10.</li><li>In general, the higher the value, the more likely the event is to happen.</li></ul></li><li>The probabilities of every possible event, when summed together, are equal to 1.</li></ul><p>$$<br>\sum_{\omega \in \Omega} P(\omega) = 1<br>$$</p><p>To get the probability of an event, we divide the number of worlds in which it occurs by the number of total possible worlds. For example, there are 36 possible worlds when rolling two dice. Only in one of these worlds, when both dice yield a 6, do we get the sum of 12. Thus, $P(12) = 1/36$, or, in words, the probability of rolling two dice and getting two numbers whose sum is 12 is 1/36. What is $P(7)$? We count and see that the sum 7 occurs in 6 worlds. Thus, $P(7) = 6/36 = 1/6$.</p><h3 id="Unconditional-Probability"><a href="#Unconditional-Probability" class="headerlink" title="Unconditional Probability"></a>Unconditional Probability</h3><p>Unconditional probability is the degree of belief in a proposition in the absence of any other evidence. All the questions that we have asked so far were questions of unconditional probability, because the result of rolling a die is not dependent on previous events.</p><h2 id="Conditional-Probability"><a href="#Conditional-Probability" class="headerlink" title="Conditional Probability"></a>Conditional Probability</h2><p>Conditional probability is the degree of belief in a proposition given some evidence that has already been revealed. As discussed in the introduction, AI can use partial information to make educated guesses about the future. To use this information, which affects the probability that the event occurs in the future, we rely on conditional probability.</p><p>Conditional probability is expressed using the following notation: $P(a \mid b)$, meaning “the probability of event a occurring given that we know event b to have occurred,” or, more succinctly, “the probability of a given b.” Now we can ask questions like what is the probability of rain today given that it rained yesterday $P(rain today \mid rain yesterday)$, or what is the probability of the patient having the disease given their test results $P(disease \mid test results)$.</p><p>Mathematically, to compute the conditional probability of a given b, we use the following formula:</p><p>$$P(a \mid b) = \frac{P(a \wedge b)}{P(b)}$$</p><p>To put it in words, the probability that a given b is true is equal to the probability of a and b being true, divided by the probability of b. An intuitive way of reasoning about this is the thought “we are interested in the events where both a and b are true (the numerator), but only from the worlds where we know b to be true (the denominator).” Dividing by b restricts the possible worlds to the ones where b is true. The following are algebraically equivalent forms to the formula above:</p><p>$$P(a \wedge b) = P(b)P(a \mid b)$$</p><p>$$P(a \wedge b) = P(a)P(b \mid a)$$</p><h2 id="Random-Varibles"><a href="#Random-Varibles" class="headerlink" title="Random Varibles"></a>Random Varibles</h2><p>A random variable is a variable in probability theory with a domain of possible values that it can take on. For example, to represent possible outcomes when rolling a die, we can define a random variable Roll, that can take on the values {0, 1, 2, 3, 4, 5, 6}. To represent the status of a flight, we can define a variable Flight that takes on the values {on time, delayed, canceled}.</p><p>Often, we are interested in the probability with which each value occurs. We represent this using a probability distribution. For example,</p><ul><li>$P(Flight = on time) = 0.6$</li><li>$P(Flight = delayed) = 0.3$</li><li>$P(Flight = canceled) = 0.1$<br>To interpret the probability distribution with words, this means that there is a 60% chance that the flight is on time, 30% chance that it is delayed, and 10% chance that it is canceled. Note that, as shown previously, the sum the probabilities of all possible outcomes is 1.</li></ul><p>A probability distribution can be represented more succinctly as a vector. For example, $P(Flight) = <0.6, 0.3, 0.1>$. For this notation to be interpretable, the values have a set order (in our case, on time, delayed, canceled).</p><h3 id="Independence"><a href="#Independence" class="headerlink" title="Independence"></a>Independence</h3><p>Independence is the knowledge that the occurrence of one event does not affect the probability of the other event. For example, when rolling two dice, the result of each die is independent from the other. Rolling a 4 with the first die does not influence the value of the second die that we roll. This is opposed to dependent events, like clouds in the morning and rain in the afternoon. If it is cloudy in the morning, it is more likely that it will rain in the morning, so these events are dependent.</p><p>Independence can be defined mathematically: events a and b are independent if and only if the probability of a and b is equal to the probability of a times the probability of b: $P(a \wedge b) = P(a)P(b)$.</p><h2 id="Bayes’-Rule"><a href="#Bayes’-Rule" class="headerlink" title="Bayes’ Rule"></a>Bayes’ Rule</h2><p>Bayes’ rule is commonly used in probability theory to compute conditional probability. In words, Bayes’ rule says that the probability of b given a is equal to the probability of a given b, times the probability of b, divided by the probability of a.</p><p>$$<br>P(b \mid a) = \frac{P(b)P(a \mid b)}{P(a)}$$</p><p>Knowing $P(a \mid b)$, in addition to $P(a)$ and $P(b)$, allows us to calculate $P(b \mid a)$. This is helpful, because knowing the conditional probability of a visible effect given an unknown cause, P(visible effect | unknown cause), allows us to calculate the probability of the unknown cause given the visible effect, P(unknown cause | visible effect). For example, we can learn P(medical test results | disease) through medical trials, where we test people with the disease and see how often the test picks up on that. Knowing this, we can calculate P(disease | medical test results), which is valuable diagnostic information.</p><h2 id="Joint-Probability"><a href="#Joint-Probability" class="headerlink" title="Joint Probability"></a>Joint Probability</h2><p>Joint probability is the likelihood of multiple events all occurring.</p><p>We need to look at the joint probabilities of all the possible outcones of thhe 2 varibles.</p><table><thead><tr><th>C = cloud</th><th>C = $\neg$ cloud</th></tr></thead><tbody><tr><td>0.4</td><td>0.6</td></tr></tbody></table><table><thead><tr><th>R = rain</th><th>R = $\neg$ rain</th></tr></thead><tbody><tr><td>0.1</td><td>0.9</td></tr></tbody></table><table><thead><tr><th></th><th>R = rain</th><th>R = $\neg$ rain</th></tr></thead><tbody><tr><td><strong>C</strong> = cloud</td><td>0.08</td><td>0.32</td></tr><tr><td><strong>C</strong> = $\neg$ cloud</td><td>0.02</td><td>0.58</td></tr></tbody></table><blockquote><p>In fact, the joint probability here is not the result of calculation, but a rule of thought.</p></blockquote><p>Now we are able to know information about the co-occurrence of the events. For example, we know that the probability of a certain day having clouds in the morning and rain in the afternoon is 0.08. The probability of no clouds in the morning and no rain in the afternoon is 0.58.</p><p>Using joint probabilities, we can deduce conditional probability. For example, if we are interested in the probability distribution of clouds in the morning given rain in the afternoon. $P(C \mid rain) = \frac{P(C, rain)}{P(rain)}$ (a side note: in probability, commas and $\wedge$ are used interchangeably. Thus, $P(C, rain) = P(C \wedge rain))$. In words, we divide the joint probability of rain and clouds by the probability of rain.</p><p>In the last equation, it is possible to view $P(rain)$ as some constant by which $P(C, rain)$ is multiplied. Thus, we can rewrite $\frac{P(C, rain)}{P(rain)} = \alpha P(C, rain)$, or $\alpha <0.08, 0.02>$. Factoring out α leaves us with the proportions of the probabilities of the possible values of C given that there is rain in the afternoon. Namely, if there is rain in the afternoon, the proportion of the probabilities of clouds in the morning and no clouds in the morning is 0.08:0.02. Note that 0.08 and 0.02 don’t sum up to 1; however, since this is the probability distribution for the random variable C, we know that they should sum up to 1. Therefore, we need to normalize the values by computing α such that $\alpha 0.08 + \alpha 0.02 = 1$. Finally, we can say that $P(C \mid rain) = <0.8, 0.2>$.</p><p>因为这中间需要包涵到cloud的两种情况,即晴天或者多云,两种情况的概率总和为1,没有第三种可能的情况,所以两种情况的等比扩大和应为1(也可以理解为矩阵加法),由此我们可以推导出对应特定条件的单一条件的概率。</p><h2 id="Probability-Rules"><a href="#Probability-Rules" class="headerlink" title="Probability Rules"></a>Probability Rules</h2><p>Negation: $P(\neg a) = 1 - P(a)$. This stems from the fact that the sum of the probabilities of all the possible worlds is 1, and the complementary literals $a$ and $\neg a$ include all the possible worlds.</p><p>Inclusion-Exclusion: $P(a \vee b) = P(a) + P(b) - P(a \wedge b)$. This can interpreted in the following way: the worlds in which a or b are true are equal to all the worlds where a is true, plus the worlds where b is true. However, in this case, some worlds are counted twice (the worlds where both a and b are true)). To get rid of this overlap, we subtract once the worlds where both a and b are true (since they were counted twice).</p><p>Here is an example from outside lecture that can elucidate this. Suppose I eat ice cream 80% of days and cookies 70% of days. If we’re calculating the probability that today I eat ice cream or cookies $P(ice cream \vee cookies)$ without subtracting $P(ice cream \wedge cookies)$, we erroneously end up with 0.7 + 0.8 = 1.5. This contradicts the axiom that probability ranges between 0 and 1. To correct for counting twice the days when I ate both ice cream and cookies, we need to subtract $P(ice cream \wedge cookies)$ once.</p><h3 id="Marginalization"><a href="#Marginalization" class="headerlink" title="Marginalization"></a>Marginalization</h3><p>$P(a) = P(a, b) + P(a, \neg b)$. The idea here is that $b$ and $\neg b$ are disjoint probabilities. That is, the probability of $b$ and $\neg b$ occurring at the same time is 0. We also know $b$ and $\neg b$ sum up to 1. Thus, when a happens, $b$ can either happen or not. When we take the probability of both a and b happening in addition to the probability of $a$ and $\neg b$, we end up with simply the probability of a.</p><p>Marginalization can be expressed for random variables the following way:</p><p>$$P(X = x_{i}) = \sum_{j}P(X = x_{i}, Y = y_{i})$$</p><p>The left side of the equation means “The probability of random variable X having the value $x_{i}$.” For example, for the variable C we mentioned earlier, the two possible values are clouds in the morning and no clouds in the morning. The right part of the equation is the idea of marginalization. $P(X = x_{i})$ is equal to the sum of all the joint probabilities of $x_{i}$ and every single value of the random variable Y.</p><h3 id="Conditioning"><a href="#Conditioning" class="headerlink" title="Conditioning"></a>Conditioning</h3><p>$P(a) = P(a \mid b)P(b) + P(a \mid \neg b)P(\neg b)$. This is $a$ similar idea to marginalization. The probability of event $a$ occurring is equal to the probability of a given $b$ times the probability of $b$, plus the probability of a given $\neg b$ time the probability of $\neg b$.</p><p>$$P(X = x_{i}) = \sum_{j}P(X = x_{i} \mid Y = y_{i})P(Y = y_{i})$$</p><p>In this formula, the random variable X takes the value $x_{i}$ with probability that is equal to the sum of the probabilities of $x_{i}$ given each value of the random variable Y multiplied by the probability of variable Y taking that value. This makes sense if we remember that $P(a \mid b) = \frac{P(a, b)}{P(b)}$. If we multiply this expression by $P(b)$, we end up with $P(a, b)$, and from here we do the same as we did with marginalization.</p><h2 id="Beyesian-Networks"><a href="#Beyesian-Networks" class="headerlink" title="Beyesian Networks"></a>Beyesian Networks</h2><p>A Bayesian network is a data structure that represents the dependencies among random variables. Bayesian networks have the following properties:</p><p>They are directed graphs.</p><ul><li>Each node on the graph represent a random variable.</li><li>An arrow from X to Y represents that X is a parent of Y. That is, the probability distribution of Y depends on the value of X.</li><li>Each node X has probability distribution $P(X \mid Parents(X))$.</li></ul><p>In other words, if we want to find the probability of events under specific conditions, in a complex Bayesian network, we only need to consider the previous conditions of the current situation and go back to the initial conditions. The conditional probability under the current conditions can be used as the result of the preconditions and go back to the initial conclusion.</p><p>We make A hypothesis that if A is the most initial condition, A indicates B, A also indicates C, B indicates C, and C indicates D. each condition contains three seeds. If we want to find the probability of a specific case in condition D under three different specific conditions of A, B, C. As shown in the following table:</p><table><thead><tr><th>A</th><th></th><th></th></tr></thead><tbody><tr><td>$\downarrow$</td><td>$\searrow$</td><td></td></tr><tr><td><strong>B</strong></td><td>$\to$</td><td><strong>C</strong></td></tr><tr><td></td><td></td><td>$\downarrow$</td></tr><tr><td></td><td></td><td><strong>D</strong></td></tr></tbody></table><p>And we assume that each of the condtions contains 3 sub cases $\alpha , \beta and \gamma$.</p><p>So now, if we want to calculate the probability of $\alpha$ in condition D, when C is in $\beta$, B is in $\gamma$ and A is also in $\gamma$. We need to combine all the circumstances to compute. As the answer follows:</p><p>$$P(A_{\gamma}, B_{\gamma}, C_{\beta}, D_{\alpha}) = P(D_{\alpha} \mid C_{\beta})P(C_{\beta} \mid A_{\gamma}, B_{\gamma})P(B_{\gamma} \mid A_{\gamma})P(A_{\gamma})$$</p><h3 id="Inference"><a href="#Inference" class="headerlink" title="Inference"></a>Inference</h3><p>We could definitively conclude new information based on the information that we already had. We can also infer new information based on probabilities. While this does not allow us to know new information for certain, it allows us to figure out the probability distributions for some values. Inference has multiple properties.</p><ul><li>Query <strong>X</strong>: the variable for which we want to compute the probability distribution.</li><li>Evidence variables <strong>E</strong>: one or more variables that have been observed for event e. For example, we might have observed that there is light rain, and this observation helps us compute the probability that the train is delayed.</li><li>Hidden variables <strong>Y</strong>: variables that aren’t the query and also haven’t been observed. For example, standing at the train station, we can observe whether there is rain, but we can’t know if there is maintenance on the track further down the road. Thus, Maintenance would be a hidden variable in this situation.</li><li>The <strong>goal</strong>: calculate $P(X \mid e)$. For example, compute the probability distribution of the Train variable (the query) based on the evidence e that we know there is light rain.</li></ul><h3 id="Inference-by-Enumeration"><a href="#Inference-by-Enumeration" class="headerlink" title="Inference by Enumeration"></a>Inference by Enumeration</h3><p>Inference by enumeration is a process of finding the probability distribution of variable X given observed evidence e and some hidden variables Y.</p><p>$$P(X \mid e) = \alpha P(X, e) = \alpha \sum_{y} P(X, e, y)$$</p><p>In this equation, $X$ stand for the query variable, $e $for the observed evidence, $y$ for all the values of the hidden variables, and $\alpha$ normalizes the result such that we end up with probabilities that add up to 1. To explain the equation in words, it is saying that the probability distribution of $X$ given $e$ is equal to a normalized probability distribution of $X$ and $e$. To get to this distribution, we sum the normalized probability of $X$, $e$, and $y$, where $y$ takes each time a different value of the hidden variables $Y$.</p><h2 id="Sampling"><a href="#Sampling" class="headerlink" title="Sampling"></a>Sampling</h2><p>Sampling is one technique of approximate inference. In sampling, each variable is sampled for a value according to its probability distribution. We will start with an example from outside lecture, and then cover the example from lecture.</p><p>Because in most cases, we don’t need to predict very accurate things, just know the probability estimation of things, which will avoid a lot of complex and cumbersome calculations. The core view of Bayes is that it is different from observing the distribution of samples under specific parameters, but to make the samples full of randomness and analyze the distribution of parameters, that is, the samples are fixed, but the parameter attributes of each sample are random.</p><h3 id="Likelihood-Weighting-似然加权"><a href="#Likelihood-Weighting-似然加权" class="headerlink" title="Likelihood Weighting 似然加权"></a>Likelihood Weighting 似然加权</h3><ul><li>Start by fixing the values for evidence variables.</li><li>Sample the non-evidence variables using conditional probabilities in the Bayesian network.</li><li>Weight each sample by its likelihood: the probability of all the evidence occurring.</li></ul><p>For example, if we have the observation that the train was on time, we will start sampling as before. We sample a value of Rain given its probability distribution, then Maintenance, but when we get to Train - we always give it the observed value, in our case, on time. Then we proceed and sample Appointment based on its probability distribution given $Train = on time$. Now that this sample exists, we weight it by the conditional probability of the observed variable given its sampled parents. That is, if we sampled Rain and got light, and then we sampled Maintenance and got yes, then we will weight this sample by $P(Train = on time \mid light, yes)$.</p><h2 id="Markov-Models"><a href="#Markov-Models" class="headerlink" title="Markov Models"></a>Markov Models</h2><p>So far, we have looked at questions of probability given some information that we observed. In this kind of paradigm, the dimension of time is not represented in any way. However, many tasks do rely on the dimension of time, such as prediction. To represent the variable of time we will create a new variable, $X$, and change it based on the event of interest, such that $X_{t}$ is the current event, $X_{t+1}$ is the next event, and so on. To be able to predict events in the future, we will use Markov Models.</p><h3 id="The-Markov-Assumption"><a href="#The-Markov-Assumption" class="headerlink" title="The Markov Assumption"></a>The Markov Assumption</h3><ul><li>将随机变量作为结点,若两个随机变量相关或者不独立,则将二者连接一条边;若给定若干随机变量,则形成一个有向图,即构成一个网络。</li><li>如果该网络是有向无环图,则这个网络称为贝叶斯网络。</li><li>如果这个图退化成线性链的方式,则得到马尔可夫模型;因为每个结点都是随机变量,将其看成各个时刻(或空间)的相关变化,以随机过程的视角,则可以看成是马尔可夫过程。</li><li>若上述网络是无向的,则是无向图模型,又称马尔可夫随机场或者马尔可夫网络。</li><li>如果在给定某些条件的前提下,研究这个马尔可夫随机场,则得到条件随机场。</li><li>如果使用条件随机场解决标注问题,并且进一步将条件随机场中的网络拓扑变成线性的,则得到线性链条件随机场。</li></ul><p>The Markov assumption is an assumption that the current state depends on only a finite fixed number of previous states. This is important to us. Think of the task of predicting weather. In theory, we could use all the data from the past year to predict tomorrow’s weather. However, it is infeasible, both because of the computational power this would require and because there is probably no information about the conditional probability of tomorrow’s weather based on the weather 365 days ago. Using the Markov assumption, we restrict our previous states (e.g. how many previous days we are going to consider when predicting tomorrow’s weather), thereby making the task manageable. This means that we might get a more rough approximation of the probabilities of interest, but this is often good enough for our needs. Moreover, we can use a Markov model based on the information of the one last event (e.g. predicting tomorrow’s weather based on today’s weather).</p><h3 id="Markov-Chain"><a href="#Markov-Chain" class="headerlink" title="Markov Chain"></a>Markov Chain</h3><p>A Markov chain is a sequence of random variables where the distribution of each variable follows the Markov assumption. That is, each event in the chain occurs based on the probability of the event before it.</p><p>To start constructing a Markov chain, we need a transition model that will specify the the probability distributions of the next event based on the possible values of the current event.</p><p>每个状态的转移只依赖于之前的n个状态,这个过程被称为1个n阶的模型,其中n是影响转移状态的数目。最简单的马尔可夫过程就是一阶过程,每一个状态的转移只依赖于其之前的那一个状态,这个也叫作马尔可夫性质。</p><p>$$P(X_{n+1} \mid X_{1} = x_{1}, X_{2} = x_{2},… , X_{n} = x_{n} = P(X_{n+1} = x \mid X_{n} = x_{n}))$$</p><h3 id="Hidden-Markov-Models"><a href="#Hidden-Markov-Models" class="headerlink" title="Hidden Markov Models"></a>Hidden Markov Models</h3><p>A hidden Markov model is a type of a Markov model for a system with hidden states that generate some observed event. This means that sometimes, the AI has some measurement of the world but no access to the precise state of the world. In these cases, the state of the world is called the hidden state and whatever data the AI has access to are the observations. Here are a few examples for this:</p><p>For a robot exploring uncharted territory, the hidden state is its position, and the observation is the data recorded by the robot’s sensors.<br>In speech recognition, the hidden state is the words that were spoken, and the observation is the audio waveforms.</p><p>When measuring user engagement on websites, the hidden state is how engaged the user is, and the observation is the website or app analytics.</p><h3 id="Sensor-Markov-Assumption"><a href="#Sensor-Markov-Assumption" class="headerlink" title="Sensor Markov Assumption"></a>Sensor Markov Assumption</h3><p>The assumption that the evidence variable depends only on the corresponding state. For example, for our models, we assume that whether people bring umbrellas to the office depends only on the weather. This is not necessarily reflective of the complete truth, because, for example, more conscientious, rain-averse people might take an umbrella with them everywhere even when it is sunny, and if we knew everyone’s personalities it would add more data to the model. However, the sensor Markov assumption ignores these data, assuming that only the hidden state affects the observation.</p><p>A hidden Markov model can be represented in a Markov chain with two layers. The top layer, variable X, stands for the hidden state. The bottom layer, variable E, stands for the evidence, the observations that we have.</p><p>Based on hidden Markov models, multiple tasks can be achieved:</p><ul><li><strong>Filtering</strong>: given observations from start until now, calculate the probability distribution for the current state. For example, given information on when people bring umbrellas form the start of time until today, we generate a probability distribution for whether it is raining today or not.</li><li><strong>Prediction</strong>: given observations from start until now, calculate the probability distribution for a future state.</li><li><strong>Smoothing</strong>: given observations from start until now, calculate the probability distribution for a past state. For example, calculating the probability of rain yesterday given that people brought umbrellas today.</li><li><strong>Most likely explanation</strong>: given observations from start until now, calculate most likely sequence of events.</li></ul>]]></content>
<categories>
<category> Artificial Intelligence </category>
</categories>
<tags>
<tag> Artificial Intelligence </tag>
<tag> 笔记 </tag>
</tags>
</entry>
<entry>
<title>Intro to AI Chapter 2 Knowledge</title>
<link href="/2022/02/20/Intro-to-AI-Chapter-2-Knowledge/"/>
<url>/2022/02/20/Intro-to-AI-Chapter-2-Knowledge/</url>
<content type="html"><![CDATA[<h1 id="Chapter-2-Knowledge"><a href="#Chapter-2-Knowledge" class="headerlink" title="Chapter 2 Knowledge"></a>Chapter 2 Knowledge</h1><ul><li>knowledge-based agents<br>Agents that reason by operating on internal representations of knowledge. Somehow inside the AI, they have some understanding of what it means to know something.</li></ul><h2 id="Terms-and-Symbols"><a href="#Terms-and-Symbols" class="headerlink" title="Terms and Symbols"></a>Terms and Symbols</h2><ul><li><p>sentence<br>An assertion about the world in a knowledge representation language.</p></li><li><p>propositional logic<br>Statement based on a logic of proposition, or just statements about the owrld.</p><ul><li><p>Proposition Symbol<br>P Q R, each of them represents a statement.</p></li><li><p>Logical Connectives<br>$\neg$ not $\wedge$ and $\vee$ or $\rightarrow$ implication $\leftrightarrow$ biconditional</p></li></ul></li><li><p>knowledge base<br>A set of sentences known by a knowledge-based agent.</p></li><li><p>Entailment<br>In every model in which sentence $\alpha$ is true, sentence $\beta$ is also true.</p></li></ul><p>$$\alpha \models \beta$$</p><ul><li>inference<br>The process of driving new sentences from old ones.</li></ul><h2 id="Inference-Algorithm"><a href="#Inference-Algorithm" class="headerlink" title="Inference Algorithm"></a>Inference Algorithm</h2><h3 id="Model-checking"><a href="#Model-checking" class="headerlink" title="Model checking"></a>Model checking</h3><ul><li>To determine if <em>KB</em> $\models \alpha$<ul><li>Enumertate all possible models</li><li>If in every model where <em>KB</em> is true, $\alpha$ is true, then <em>KB</em> entails $\alpha$<br>(check whether KB is true first, and then check whether the Query is true under the circunstance that KB is true)</li></ul></li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">model_check</span>(<span class="params">knowledge, query</span>):</span><br><span class="line"> <span class="comment"># Checks if knowledge base entails query</span></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">check_all</span>(<span class="params">knowledge, query, symbols, model</span>):</span><br><span class="line"> <span class="comment"># If model has an assignment for each symbol</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> symbols:</span><br><span class="line"> <span class="comment"># If knowledge base is true in model, then the query must be true.</span></span><br><span class="line"> <span class="keyword">if</span> knowledge.evaluate(model):</span><br><span class="line"> <span class="keyword">return</span> query.evaluate(model)</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="comment"># Choose one of the unused remaining symbol.</span></span><br><span class="line"> remaining = symbols.copy()</span><br><span class="line"> p = remaining.pop()</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Creat a model where symbol is true.</span></span><br><span class="line"> model_true = model.copy()</span><br><span class="line"> model_true[p] = <span class="literal">True</span></span><br><span class="line"> <span class="comment"># Creat a model where symbol is true.</span></span><br><span class="line"> model_false = model.copy()</span><br><span class="line"> model_false[p] = <span class="literal">False</span></span><br><span class="line"> <span class="comment"># Ensure entailment holds both circumstances</span></span><br><span class="line"> <span class="keyword">return</span>(check_all(knowledge, query, remaining, model_true) <span class="keyword">and</span> check_all(knowledge, query, remaining, model_false))</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Get all symbols in both knowledge and query</span></span><br><span class="line"> symbols = <span class="built_in">set</span>.union(knowledge.symbols(), query.symbols())</span><br><span class="line"></span><br><span class="line"> <span class="comment">#check that knowledge base entails query</span></span><br><span class="line"> <span class="keyword">return</span> check_all(knowledge, query, symbols, <span class="built_in">dict</span>()) </span><br></pre></td></tr></table></figure><h2 id="Knowledge-Engineering"><a href="#Knowledge-Engineering" class="headerlink" title="Knowledge Engineering"></a>Knowledge Engineering</h2><p>We can use a computer to be able to represent knowledge and draw conclusions based on that knowledge.<br>At anytime we can translate something into propositional logic symbols, type of aproach can be useful.</p><h2 id="Inference-Rules"><a href="#Inference-Rules" class="headerlink" title="Inference Rules"></a>Inference Rules</h2><p>Model Checking is not an efficient algorithm because it has to consider every possible model before giving the answer (a reminder: a query R is true if under all the models (truth assignments) where the KB is true, R is true as well). Inference rules allow us to generate new information based on existing knowledge without considering every possible model.</p><p>Inference rules are usually represented using a horizontal bar that separates the top part, the premise, from the bottom part, the conclusion. The premise is whatever knowledge we have, and the conclusion is what knowledge can be generated based on the premise.</p><p>In this example, our premise consists of the following propositions:</p><ul><li>If it is raining, then Harry is inside.</li><li>It is raining.</li></ul><p>Based on this, most reasonable humans can conclude that</p><ul><li>Harry is inside.</li></ul><h3 id="Modus-Ponens"><a href="#Modus-Ponens" class="headerlink" title="Modus Ponens"></a>Modus Ponens</h3><p>The type of inference rule we use in this example is Modus Ponens, which is a fancy way of saying that if we know an implication and its antecedent to be true, then the consequent is true as well.</p><p>$$\alpha \rightarrow \beta$$</p><p>$$\alpha$$</p><hr><p>$$\beta$$</p><p>This means if we have known the deduction that $\alpha$ implicates $\beta$, and also we have confirmed that $\alpha$ is true, so that we can also conclude that $\beta$ is true.</p><h3 id="And-Elimination"><a href="#And-Elimination" class="headerlink" title="And Elimination"></a>And Elimination</h3><p>If an And proposition is true, then any one atomic proposition within it is true as well.</p><p>$$\alpha \wedge \beta$$</p><hr><p>$$\alpha$$</p><h3 id="Double-Negation-Elimination"><a href="#Double-Negation-Elimination" class="headerlink" title="Double Negation Elimination"></a>Double Negation Elimination</h3><p>A proposition that is negated twice is true. For example, consider the proposition “It is not true that Harry did not pass the test”. We can parse it the following way: “It is not true that (Harry did not pass the test)”, or “$\neg$(Harry did not pass the test)”, and, finally “$\neg$($\neg$(Harry passed the test)).” The two negations cancel each other, marking the proposition “Harry passed the test” as true.</p><p>$$(\neg(\neg \alpha))$$</p><hr><p>$$\alpha$$</p><h3 id="Implication-Elimination"><a href="#Implication-Elimination" class="headerlink" title="Implication Elimination"></a>Implication Elimination</h3><p>An implication is equivalent to an Or relation between the negated antecedent and the consequent. As an example, the proposition “If it is raining, Harry is inside” is equivalent to the proposition “(it is not raining) or (Harry is inside).”</p><p>$$\alpha \rightarrow \beta$$</p><hr><p>$$\neg \alpha \vee \beta$$</p><h3 id="Biconditional-Elimination"><a href="#Biconditional-Elimination" class="headerlink" title="Biconditional Elimination"></a>Biconditional Elimination</h3><p>A biconditional proposition is equivalent to an implication and its inverse with an And connective.</p><p>$$\alpha \Leftrightarrow \beta$$</p><hr><p>$$(\alpha \rightarrow \beta) \wedge (\beta \rightarrow \alpha)$$</p><h3 id="De-Morgan’s-Law"><a href="#De-Morgan’s-Law" class="headerlink" title="De Morgan’s Law"></a>De Morgan’s Law</h3><p>It is possible to turn an And connective into an Or connective. That is, for the And proposition earlier to be true, at least one of the propositions in the Or propositions must be true. Similarly, it is possible to conclude the reverse.</p><p>$$\neg(\alpha \wedge \beta)$$</p><hr><p>$$\neg \alpha \vee \neg \beta$$</p><p>$$\neg(\alpha \vee \beta)$$</p><hr><p>$$\neg \alpha \wedge \neg \beta$$</p><h3 id="Distributive-Property"><a href="#Distributive-Property" class="headerlink" title="Distributive Property"></a>Distributive Property</h3><p>A proposition with two elements that are grouped with And or Or connectives can be distributed, or broken down into, smaller units consisting of And and Or.</p><p>$$(\alpha \wedge(\beta \vee \gamma))$$</p><hr><p>$$(\alpha \wedge \beta)\vee(\alpha \wedge \beta)$$</p><h2 id="Theorem-Proving"><a href="#Theorem-Proving" class="headerlink" title="Theorem Proving"></a>Theorem Proving</h2><ul><li>Initial state: starting knowledge base</li><li>Actions: inference rules</li><li>Transition model: new knowledge base after inference</li><li>Goal test: checking whether the statement that we are trying to prove is in the KB</li><li>Path cost function: the number of steps in the proof</li></ul><h2 id="Resolution"><a href="#Resolution" class="headerlink" title="Resolution"></a>Resolution</h2><p>Resolution is a powerful inference rule that states that if one of two atomic propositions in an Or proposition is false, the other has to be true. More formally, we can define resolution the following way:</p><p>$$P \vee Q$$<br>$$\neg P$$</p><hr><p>$$Q$$</p><p>Resolution relies on Complementary Literals, two of the same atomic propositions where one is negated and the other is not, such as P and $\neg$ P.</p><p>Complementary literals allow us to generate new sentences through inferences by resolution. Thus, inference algorithms locate complementary literals to generate new knowledge.</p><h2 id="Clause"><a href="#Clause" class="headerlink" title="Clause"></a>Clause</h2><p>A <strong>Clause</strong> is a disjunction of <strong>literals</strong> (a propositional symbol or a negation of a propositional symbol, such as P, $\neg$ P). A disjunction consists of propositions that are connected with an Or logical connective (P $\vee$ Q $\vee$ R). A <strong>conjunction</strong>, on the other hand, consists of propositions that are connected with an <strong>And</strong> logical connective (P $\wedge$ Q $\wedge$ R). Clauses allow us to convert any logical statement into a <strong>Conjunctive Normal Form</strong> (CNF), which is a conjunction of clauses, for example: (A $\vee$ B $\vee$ C) $\wedge$ (D $ \vee \neg$ E) $\wedge$ (F $\vee$ G).</p><h2 id="Steps-in-Conversion-of-Propositions-to-Conjunctive-Normal-Form"><a href="#Steps-in-Conversion-of-Propositions-to-Conjunctive-Normal-Form" class="headerlink" title="Steps in Conversion of Propositions to Conjunctive Normal Form"></a>Steps in Conversion of Propositions to Conjunctive Normal Form</h2><ul><li>Eliminate biconditionals<ul><li>Turn ($\alpha \Leftrightarrow \beta$) into ($\alpha \rightarrow \beta$) $\wedge$ ($\beta \rightarrow \alpha$).</li></ul></li><li>Eliminate implications<ul><li>Turn ($\alpha \rightarrow \beta$) into $\neg \alpha \vee \beta$.</li></ul></li><li>Move negation inwards until only literals are being negated (and not clauses), using De Morgan’s Laws.<ul><li>Turn $\neg(\alpha \wedge \beta)$ into $\neg \alpha \vee \neg \beta$</li></ul></li></ul><p>Here’s an example of converting $(P \vee Q) \rightarrow R$ to Conjunctive Normal Form:</p><p>$(P \vee Q) \rightarrow R$<br>$\neg(P \vee Q) \vee R$ ==Eliminate implication==<br>$(\neg P \wedge \neg Q) \vee R$ ==De Morgan’s Law==<br>$(\neg P \vee R) \wedge (\neg Q \vee R)$ ==Distributive Law==<br>At this point, we can run an inference algorithm on the conjunctive normal form. Occasionally, through the process of inference by resolution, we might end up in cases where a clause contains the same literal twice. In these cases, a process called factoring is used, where the duplicate literal is removed. For example, $(P \vee Q \vee S) \wedge (\neg P \vee R \vee S)$ allow us to infer by resolution that $(Q \vee S \vee R \vee S)$. The duplicate $S$ can be removed to give us $(Q \vee R \vee S)$.</p><p>Resolving a literal and its negation, i.e. $\neg P$ and $P$, gives the <em>==empty clause()==</em>. The empty clause is always false, and this makes sense because it is impossible that both $P$ and $\neg P$ are true. This fact is used by the resolution algorithm.</p><ul><li>To determine if $KB \models \alpha$:<ul><li>Check: is $(KB \wedge \neg \alpha)$ a contradiction?</li><li>If so, then $KB \models \alpha$.</li><li>Otherwise, no entailment.</li></ul></li></ul><p>Proof by contradiction is a tool used often in computer science. If our knowledge base is true, and it contradicts $\neg \alpha$, it means that $\neg \alpha$ is false, and, therefore, $\alpha$ must be true. More technically, the algorithm would perform the following actions:</p><p>To determine if $KB \models \alpha$:</p><ul><li>Convert $(KB \wedge \neg \alpha)$ to Conjunctive Normal Form.</li><li>Keep checking to see if we can use resolution to produce a new clause.</li><li>If we ever produce the empty clause (equivalent to False), congratulations! We have arrived at a contradiction, thus proving that $KB \models \alpha$.</li><li>However, if contradiction is not achieved and no more clauses can be inferred, there is no entailment.</li></ul><blockquote><p><strong>Here is an example that illustrates how this algorithm might work:</strong><br>Does $(A \vee B) \wedge (\neg B \vee C) \wedge (\neg C)$ entail $A$?<br>First, to prove by contradiction, we assume that A is false. Thus, we arrive at $(A \vee B) \wedge (\neg B \vee C) \wedge (\neg C) \wedge (\neg A)$.<br>Now, we can start generating new information. Since we know that $C$ is false $(\neg C)$, the only way $(\neg B \vee C)$ can be true is if $B$ is false, too. Thus, we can add $(\neg B)$ to our $KB$.<br>Next, since we know $(\neg B)$, the only way $(A \vee B)$ can be true is if $A$ is true. Thus, we can add $(A)$ to our $KB$.<br>Now our KB has two complementary literals, $(A)$ and $(\neg A)$. We resolve them, arriving at the empty set, $()$. The empty set is false by definition, so we have arrived at a contradiction.</p></blockquote><h2 id="First-Order-Logic-一阶逻辑"><a href="#First-Order-Logic-一阶逻辑" class="headerlink" title="First Order Logic 一阶逻辑"></a>First Order Logic 一阶逻辑</h2><p><strong>First order logic</strong> is another type of logic that allows us to express more complex ideas more succinctly than propositional logic. <strong>First order logic</strong> uses two types of symbols: Constant Symbols and Predicate Symbols. Constant symbols represent objects, while predicate symbols are like relations or functions that take an argument and return a true or false value.</p><p>For example, we return to the logic puzzle with different people and house assignments at Hogwarts. The constant symbols are people or houses, like Minerva, Pomona, Gryffindor, Hufflepuff, etc. The predicate symbols are properties that hold true or false of some constant symbols. For example, we can express the idea that Minerva is a person using the sentence $Person(Minerva)$. Similarly, we can express the idea the Gryffindor is a house using the sentence $House(Gryffindor)$. All the logical connectives work in first order logic the same way as before. For example, $\neg House(Minerva)$ expresses the idea that Minerva is not a house. A predicate symbol can also take two or more arguments and express a relation between them. For example, BelongsTo expresses a relation between two arguments, the person and the house to which the person belongs. Thus, the idea that Minerva belongs to Gryffindor can be expressed as $BelongsTo(Minerva, Gryffindor)$. First order logic allows having one symbol for each person and one symbol for each house. This is more succinct than propositional logic, where each person—house assignment would require a different symbol.</p><h3 id="Universal-Quantification"><a href="#Universal-Quantification" class="headerlink" title="Universal Quantification"></a>Universal Quantification</h3><p><strong>Quantification</strong> is a tool that can be used in first order logic to represent sentences without using a specific constant symbol. Universal quantification uses the symbol $\forall$ to express “for all.” So, for example, the sentence $\forall x. BelongsTo(x, Gryffindor) \rightarrow \neg BelongsTo(x, Hufflepuff) $ expresses the idea that it is true for every symbol that if this symbol belongs to Gryffindor, it does not belong to Hufflepuff.</p><h3 id="Existential-Quantification"><a href="#Existential-Quantification" class="headerlink" title="Existential Quantification"></a>Existential Quantification</h3><p><strong>Existential quantification</strong> is an idea parallel to universal quantification. However, while universal quantification was used to create sentences that are true for all x, existential quantification is used to create sentences that are true for at least one x. It is expressed using the symbol $\exists$. For example, the sentence $\exists x. House(x) \wedge BelongsTo(Minerva, x)$ means that there is at least one symbol that is both a house and that Minerva belongs to it. In other words, this expresses the idea that Minerva belongs to a house.</p><p>Existential and universal quantification can be used in the same sentence. For example, the sentence $\forall x. Person(x) \rightarrow (\forall y. House(y) \wedge BelongsTo(x, y))$ expresses the idea that if $x$ is a person, then there is at least one house, $ y$ , to which this person belongs. In other words, this sentence means that every person belongs to a house.</p><p>There are other types of logic as well, and the commonality between them is that they all exist in pursuit of representing information. These are the systems we use to represent knowledge in our AI.</p>]]></content>
<categories>
<category> Artificial Intelligence </category>
</categories>
<tags>
<tag> Artificial Intelligence </tag>
<tag> 笔记 </tag>
</tags>
</entry>
<entry>
<title>Intro to AI Chapter 1 Search</title>
<link href="/2022/02/18/Intro-to-AI-Chapter-1-Search/"/>
<url>/2022/02/18/Intro-to-AI-Chapter-1-Search/</url>
<content type="html"><![CDATA[<h1 id="Chapter-1-Search"><a href="#Chapter-1-Search" class="headerlink" title="Chapter 1 Search"></a>Chapter 1 Search</h1><h2 id="Some-Terminology"><a href="#Some-Terminology" class="headerlink" title="Some Terminology"></a>Some Terminology</h2><ul><li><p>agent:<br><strong>Entity</strong> that perceives its environment (is able to perceive something around it) and acts upon that environment in some way.</p></li><li><p>state:<br><strong>Just some figuration</strong> of the agent in its environment.</p></li><li><p>initial state:<br>One such state where <strong>we are going to start from</strong>, the starting point of search algorithm.</p></li><li><p>actions:<br>Choices that can be made in a state.<br>We are going to effectively define a function called actions.<br><strong>Actions(s)</strong> returns <strong>the set of all actions</strong> that can be executed in state s.<br>Only valid in certain states, like s.</p></li><li><p>transition model:<br>A description of what state results from performing any applicable action in any state. Focusing on how it is that <strong>states and actions are related to each other</strong>.<br>Define as a function. <strong>Result(s, a)</strong> returns the state resulting from performing action a in state s. <strong>2 inputs, state s and action a.</strong></p></li><li><p>state space<br><strong>The set of all states</strong> reachable from the initial state by any sequence of actions.<br>Simplified to a directed graph, the nodes represent one of the state and the edges represent the actions we can take in any particular state.</p></li><li><p>goal test<br>Way to determine whether a given state is a <strong>goal state</strong>.</p></li><li><p>path cost<br>Numerical cost associated with a given path. Let AI find <strong>the minimum path cost</strong>.</p></li></ul><h2 id="Graph-Searching"><a href="#Graph-Searching" class="headerlink" title="Graph Searching"></a>Graph Searching</h2><ul><li><p>stack<br>A data structure that is last-in first-out.<br>Applied in DFS algorithm.</p></li><li><p>queue<br>A data structure that is a first-in first-out.<br>Applied in BFS(Breadth first searching) algorithm.</p></li></ul><h2 id="Improment"><a href="#Improment" class="headerlink" title="Improment"></a>Improment</h2><ul><li><p>uninformed search<br>Search strategy that uses no problem-specific knowledge.<br>Based on BFS and DFS algorithm, no need to care about where the final destination is.</p></li><li><p>informed search<br>Search strategy that uses problem-specific knowledge to find soulutions more effectively.</p></li></ul><h3 id="Improved-algorithm-on-BFS-amp-DFS"><a href="#Improved-algorithm-on-BFS-amp-DFS" class="headerlink" title="Improved algorithm on BFS & DFS"></a>Improved algorithm on BFS & DFS</h3><ul><li>greedy best-first search (GBFS)<br>Search algorithmn that expands the node that is cloest to the goal, as estimated by a heuristic function <em><strong>h(n)</strong></em><br><em><strong>Why is greedy?</strong></em> It’s only making the best desition, locally.</li></ul><blockquote><p><strong>Manhattan Distance</strong><br>One specific type od heurstic, only veetically and horizontally allowed, to calculate the distance and comapare.</p></blockquote><ul><li>A* search<br>Search algorithm that expands node with lowest value of <em><strong>g(n) + h(n)</strong></em><br><em><strong>h(n)</strong></em> is the estimated cost to goal, equal to that in GBFS.<br><em><strong>g(n)</strong></em> is the cost to reach node, which means how many steps that I have to take in order to get to the current position.</li></ul><blockquote><p><strong>Optimal Only If</strong></p></blockquote><ol><li><em><strong>h(n)</strong></em> is admissible (never overestimate the true cost)</li><li><em><strong>h(n)</strong></em> is consistent (for every node <strong>n</strong>, and successor <strong>n’</strong> with step cost <strong>c</strong>, <em><strong>h(n) ≤ h(n’) + c</strong></em>. The distance you except must be shorter than the actual distance, or just equal to the actual distance. In this way we call that <strong>h(x)</strong> is admissable and optimistic.</li></ol><h2 id="Adversarial-Search"><a href="#Adversarial-Search" class="headerlink" title="Adversarial Search"></a>Adversarial Search</h2><ul><li>Minimax (recursive algorithm)<br>The situation is defined in a tic-tac-toe game. The final result of the game has been reduced mathematically to just this idea of, try and maximaze the score. X player wants the score be higher, O player wants the score be lower as possible.<br><em><strong>MAX(X)</strong></em> : maximize the score that <em>X</em> will get.<br><em><strong>MIN(O)</strong></em> : minimize the score that <em>O</em> will get.</li></ul><blockquote><p> <strong>A Determination of the Game Rules</strong><br>If O player win the game, the final result of the game is <strong>-1</strong>, by contrary, the result is <strong>1</strong> if O player win the game; the result will be <strong>0</strong> if neither of 2 players win the game.</p></blockquote><blockquote><p><strong>Functions</strong></p></blockquote><ol><li>$ S_{0} $: initial state.</li><li>PLAYER(s): returns which player to move in state s.</li><li>ACTIONS(s): returns legal moves in state s.</li><li>RESULTS(s, a): returns stater after actions a taken in state s.</li><li>TERMINAL(s): checks if state s is a terminal state.</li><li>UTILITY(s): final numerical value for terminal state s.</li></ol><p>Given a state <strong>s</strong>:</p><ul><li>MAX picks action <em><strong>a</strong></em> in <em><strong>ACTIONS(s)</strong></em> that produces highest value of <em><strong>MIN-VALUE(RESULT(s, a))</strong></em>.</li><li>MIN picks action <em><strong>a</strong></em> in <em><strong>ACTIONS(s)</strong></em> that produces smallest value of <em><strong>MAX-VALUE(RESULT(s, a))</strong></em>.</li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">functiuon MAX_VALUE(state):</span><br><span class="line"> <span class="keyword">if</span> TERMINAL(state):</span><br><span class="line"> <span class="keyword">return</span> UTILITY(state) </span><br><span class="line"> <span class="comment"># the utility function just knows what the value is</span></span><br><span class="line"> v = -∞ </span><br><span class="line"> <span class="comment"># the value of the state, the initial value is as small as possible</span></span><br><span class="line"> <span class="keyword">for</span> action <span class="keyword">in</span> ACTIONS(state):</span><br><span class="line"> v = MAX(v, MIN_VALUE(RESULT(action, state)))</span><br><span class="line"> <span class="keyword">return</span> v</span><br><span class="line"></span><br><span class="line">function MIN_VALUE(state):</span><br><span class="line"> <span class="keyword">if</span> TERMINAL(state):</span><br><span class="line"> <span class="keyword">return</span> UTILITY(state) </span><br><span class="line"> <span class="comment"># the utility function just knows what the value is</span></span><br><span class="line"> v = ∞ </span><br><span class="line"> <span class="comment"># the value of the state, the initial value is as big as possible</span></span><br><span class="line"> <span class="keyword">for</span> action <span class="keyword">in</span> ACTIONS(state):</span><br><span class="line"> v = MIN(v, MIN_VALUE(RESULT(action, state)))</span><br><span class="line"> <span class="keyword">return</span> v</span><br></pre></td></tr></table></figure><p>Figure out what the best move to make is by recursively using these maxValue and minValue, maxValue calls minValue, minValue calls maxValue, back and forth, all the way until we reach a terminal state, at which our algorithm can simply return the utiliyu of that particular state.</p><h3 id="Improved-algorithm-on-adversarial-search"><a href="#Improved-algorithm-on-adversarial-search" class="headerlink" title="Improved algorithm on adversarial search"></a>Improved algorithm on adversarial search</h3><ul><li><p>Alpha-Beta Pruning<br>When there is a sub-selection with a lower or higher score than the Alpha-choice appears in the Beta-choice, abandon the exploration of the remaining sub-selection in the Beta-choice. It depends on either you are a value-maximized player or a valur-minimized player.</p></li><li><p>Depth-Limited Minimax<br>Minimax algorithm atarts with an initial state, cosiders all the possible actions and all the possible actions after that.</p><blockquote><p><em><strong>An added new function</strong></em></p></blockquote></li></ul><p><strong>evaluation funtion</strong><br>Function that estimated the expected utility of the game from a given state.</p><p>When there are too many choices to obtain results at an acceptable cost(time or space), then approximately limit the number of depth levels. </p>]]></content>
<categories>
<category> Artificial Intelligence </category>
</categories>
<tags>
<tag> Artificial Intelligence </tag>
<tag> 笔记 </tag>
</tags>
</entry>
</search>