-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.json
1 lines (1 loc) · 721 KB
/
search.json
1
[{"title":"1分钟了解闭包的本质","url":"/2021/03/31/1%E5%88%86%E9%92%9F%E4%BA%86%E8%A7%A3%E9%97%AD%E5%8C%85%E7%9A%84%E6%9C%AC%E8%B4%A8/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test1</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test2</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">var</span> b = <span class=\"number\">2</span>;</span><br><span class=\"line\"> a++</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a);</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">var</span> a = <span class=\"number\">1</span>;</span><br><span class=\"line\"> <span class=\"keyword\">return</span> test2;</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">var</span> test3 = test1();</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(test3);</span><br><span class=\"line\">test3(); <span class=\"comment\">// 2</span></span><br><span class=\"line\">test3(); <span class=\"comment\">// 3</span></span><br><span class=\"line\">test3(); <span class=\"comment\">// 4</span></span><br><span class=\"line\">test3(); <span class=\"comment\">// 5</span></span><br></pre></td></tr></table></figure></div>\n\n<p>①当一个函数A被声明时,其作用域链第0位为GO<br>②函数A执行时,生成AO,其作用域链第0位变为函数A AO<br>③函数A内函数B被声明,此时其作用域链同函数A作用域链,将函数B return给全局<br>④函数A执行完毕,销毁自己的AO,函数A执行结果即函数B,声明全局变量接收函数B<br>⑤执行该函数,即执行函数B,此时函数B生成自己的AO,其作用域第0位由原来函数A AO替换为函数B AO<br>⑥函数B执行完毕,函数B销毁自己的AO,此时函数B 作用域链函数A的AO被保留下来<br>⑦由于自由变量(一个变量在当前作用域未被定义,但被使用了)的查找沿作用域链查找,找到函数A AO,因此函数外部可以访问到函数A中的变量值</p>\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"CSS-清除浮动","url":"/2020/12/21/CSS-%E6%B8%85%E9%99%A4%E6%B5%AE%E5%8A%A8/","content":"<p>清除浮动的五种方法</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-给浮动元素的容器设置高度(添加浮动)\"><a href=\"#1-给浮动元素的容器设置高度(添加浮动)\" class=\"headerlink\" title=\"1.给浮动元素的容器设置高度(添加浮动)\"></a>1.给浮动元素的容器设置高度(添加浮动)</h1><p>首先看下面这行代码,我们为两个div中的li标签添加浮动,希望可以将这些标签元素分成两行显示:</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/IzIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>然而事与愿违,我们发现两个div的li标签全都挤在一起了。</p>\n<p>原因是我们的父元素没有设置高度,无法撑开足够的空间让子元素浮动</p>\n<p>给父元素设置高度:</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/NzIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>给父容器添加浮动同样可以实现:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">div {</span><br><span class=\"line\"> float: left</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>只要浮动在有高度的容器中,这个浮动就不会影响后续浮动。</p>\n<p>网页开发中,这种方法会改变整体布局,所以很少使用。</p>\n<hr>\n<h1 id=\"2-clear-both\"><a href=\"#2-clear-both\" class=\"headerlink\" title=\"2.clear:both\"></a>2.clear:both</h1><p>clear:both就是清除左右浮动,我们在需要清除浮动的box2中添加这个属性:</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/PzIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>但这个方法有一个致命的缺陷,我们可以看到box2中的margin失效了。</p>\n<hr>\n<h1 id=\"3-邻接元素处理(外墙法和内墙法)\"><a href=\"#3-邻接元素处理(外墙法和内墙法)\" class=\"headerlink\" title=\"3.邻接元素处理(外墙法和内墙法)\"></a>3.邻接元素处理(外墙法和内墙法)</h1><h2 id=\"3-1-外墙法\"><a href=\"#3-1-外墙法\" class=\"headerlink\" title=\"3.1.外墙法\"></a>3.1.外墙法</h2><p>我们在两个div之间,新建一个div,在这个div中添加clear:both,相当于一堵墙,隔开两个div,让墙后的浮动元素不再跟随墙前浮动元素:</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/CzIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>这种方法虽然可以将两个div分隔开,但两个div没有高度。</p>\n<hr>\n<h2 id=\"3-2-内墙法\"><a href=\"#3-2-内墙法\" class=\"headerlink\" title=\"3.2.内墙法\"></a>3.2.内墙法</h2><p>通过内墙法,第一个div能够拥有高度:</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/uzIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h1 id=\"4-overflow-hidden-overflow-auto\"><a href=\"#4-overflow-hidden-overflow-auto\" class=\"headerlink\" title=\"4.overflow:hidden(overflow:auto)\"></a>4.overflow:hidden(overflow:auto)</h1><p>给浮动元素容器添加overflow:hidden</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/KPIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h1 id=\"5-after伪元素\"><a href=\"#5-after伪元素\" class=\"headerlink\" title=\"5.:after伪元素\"></a>5.:after伪元素</h1><p>给浮动元素的容器添加一个clearfix,给这个class一个:after伪元素,元素末尾添加一个看不见的块元素:</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/etIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<blockquote>\n<p>内容参考自:<a href=\"https://www.cnblogs.com/gchlcc/p/5824200.html\">浮动的清除 – 四种方法</a></p>\n</blockquote>\n","categories":["CSS"],"tags":["CSS","CSS布局"]},{"title":"CSS经典布局-三栏布局","url":"/2020/12/04/CSS%E7%BB%8F%E5%85%B8%E5%B8%83%E5%B1%80-%E4%B8%89%E6%A0%8F%E5%B8%83%E5%B1%80/","content":"<p>三栏布局是面试中非常常见的经典布局,左右区域宽度固定中间区域自适应,优先加载中间区域内容</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-圣杯布局\"><a href=\"#1-圣杯布局\" class=\"headerlink\" title=\"1.圣杯布局\"></a>1.圣杯布局</h1><p>实现流程:</p>\n<ul>\n<li>首先设定好header和footer,使其横向占满,便于后面观察</li>\n<li>由于需要优先加载中间区域,所以center写在最前优先加载,三列设置浮动和相对定位,清除footer浮动</li>\n<li>为方便观察,左右设置不同宽度,中间宽度100%自适应</li>\n<li>因浮动影响,整个内容区域被中间区域center充满,left容器和right容器被挤到下面</li>\n<li>通过负外边距margin-left:-100%,将left容器挤到正上方,此时left容器会盖住部分center区域</li>\n<li>设置外部容器container的padding值将left和right所需空间空出来</li>\n<li>left容器此时并未处于最右侧,设置left相对定位,将left调整到最左侧</li>\n<li>同理,通过magin-left:负自身宽度和相对定位,将right调整至最右侧</li>\n</ul>\n<iframe width=\"100%\" height=\"330\" src=\"//jsrun.net/aSwKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"HTML\"><figure class=\"iseeu highlight /html\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"tag\"><<span class=\"name\">header</span>></span>头部<span class=\"tag\"></<span class=\"name\">header</span>></span></span><br><span class=\"line\"><span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">class</span>=<span class=\"string\">"container"</span>></span></span><br><span class=\"line\"> <span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">class</span>=<span class=\"string\">"center"</span>></span>主区域<span class=\"tag\"></<span class=\"name\">div</span>></span></span><br><span class=\"line\"> <span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">class</span>=<span class=\"string\">"left"</span>></span>左区域<span class=\"tag\"></<span class=\"name\">div</span>></span></span><br><span class=\"line\"> <span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">class</span>=<span class=\"string\">"right"</span>></span>右区域<span class=\"tag\"></<span class=\"name\">div</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\">footer</span>></span>底部<span class=\"tag\"></<span class=\"name\">footer</span>></span></span><br></pre></td></tr></table></figure></div>\n\n<details>\n <summary>展开CSS样式</summary>\n <div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"> * {</span><br><span class=\"line\"> <span class=\"attribute\">margin</span>: <span class=\"number\">0</span>;</span><br><span class=\"line\"> <span class=\"attribute\">padding</span>: <span class=\"number\">0</span>;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-tag\">body</span> {</span><br><span class=\"line\"> <span class=\"attribute\">min-width</span>: <span class=\"number\">300px</span>;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-tag\">header</span> {</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, silver , snow);</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\"> <span class=\"attribute\">height</span>: <span class=\"number\">40px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">40px</span>;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">padding</span>: <span class=\"number\">0</span> <span class=\"number\">100px</span> <span class=\"number\">0</span> <span class=\"number\">100px</span>;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.center</span> {</span><br><span class=\"line\"> <span class=\"attribute\">float</span>: left;</span><br><span class=\"line\"> <span class=\"attribute\">position</span>: relative;</span><br><span class=\"line\"> <span class=\"attribute\">width</span>: <span class=\"number\">100%</span>;</span><br><span class=\"line\"> <span class=\"attribute\">height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, red , pink);</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.left</span> {</span><br><span class=\"line\"> <span class=\"attribute\">float</span>: left;</span><br><span class=\"line\"> <span class=\"attribute\">position</span>: relative;</span><br><span class=\"line\"> <span class=\"attribute\">width</span>: <span class=\"number\">100px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, yellow , snow);;</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\"> <span class=\"attribute\">margin-left</span>: -<span class=\"number\">100%</span>;</span><br><span class=\"line\"> <span class=\"attribute\">right</span>: <span class=\"number\">100px</span>;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.right</span> {</span><br><span class=\"line\"> <span class=\"attribute\">float</span>: left;</span><br><span class=\"line\"> <span class=\"attribute\">position</span>: relative;</span><br><span class=\"line\"> <span class=\"attribute\">width</span>: <span class=\"number\">100px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, skyblue , snow);;</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\"> <span class=\"attribute\">margin-left</span>: -<span class=\"number\">100px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">right</span>: -<span class=\"number\">100px</span>;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-tag\">footer</span> {</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, silver , snow);</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\"> <span class=\"attribute\">height</span>: <span class=\"number\">40px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">40px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">clear</span>: both;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n</details>\n\n<hr>\n<h1 id=\"2-双飞翼布局\"><a href=\"#2-双飞翼布局\" class=\"headerlink\" title=\"2.双飞翼布局\"></a>2.双飞翼布局</h1><p>实现流程:</p>\n<ul>\n<li>双飞翼布局与圣杯布局相似,主要差别体现在对宽度自适应的中间区域处理上</li>\n<li>圣杯布局通过设置外部容器内边距控制左右空间,双飞翼布局通过设置中间区域center外边距控制左右空间</li>\n<li>center容器宽度为100%,如果直接通过负外边距调整边栏会重叠在center上</li>\n<li>通过给center包裹一个父容器wrapper,父容器设置浮动和宽度,center只设置外边距margin,这样center外边距只会影响到父容器,不会影响到其他区域</li>\n</ul>\n<iframe width=\"100%\" height=\"330\" src=\"//jsrun.net/Y4wKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"HTML\"><figure class=\"iseeu highlight /html\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"tag\"><<span class=\"name\">header</span>></span>头部<span class=\"tag\"></<span class=\"name\">header</span>></span></span><br><span class=\"line\"> <span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">class</span>=<span class=\"string\">"wrapper"</span>></span></span><br><span class=\"line\"> <span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">class</span>=<span class=\"string\">"center"</span>></span>主区域<span class=\"tag\"></<span class=\"name\">div</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\">div</span> <span class=\"attr\">class</span>=<span class=\"string\">"left"</span>></span>左区域<span class=\"tag\"></<span class=\"name\">div</span>></span></span><br><span class=\"line\"> <span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">class</span>=<span class=\"string\">"right"</span>></span>右区域<span class=\"tag\"></<span class=\"name\">div</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\">footer</span>></span>底部<span class=\"tag\"></<span class=\"name\">footer</span>></span></span><br></pre></td></tr></table></figure></div>\n\n<details>\n <summary>展开CSS样式</summary>\n <div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\">* {</span><br><span class=\"line\"><span class=\"attribute\">margin</span>: <span class=\"number\">0</span>;</span><br><span class=\"line\"><span class=\"attribute\">padding</span>: <span class=\"number\">0</span>;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-tag\">header</span> {</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, silver , snow);</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\"> <span class=\"attribute\">height</span>: <span class=\"number\">40px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">40px</span>;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.wrapper</span> {</span><br><span class=\"line\"> <span class=\"attribute\">width</span>: <span class=\"number\">100%</span>;</span><br><span class=\"line\"> <span class=\"attribute\">float</span>: left;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.center</span> {</span><br><span class=\"line\"> <span class=\"comment\">/* float: left; */</span></span><br><span class=\"line\"> <span class=\"comment\">/* width: 100%; */</span></span><br><span class=\"line\"> <span class=\"attribute\">height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, red , snow);</span><br><span class=\"line\"> <span class=\"attribute\">margin</span>: <span class=\"number\">0</span> <span class=\"number\">120px</span> <span class=\"number\">0</span> <span class=\"number\">100px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.left</span> {</span><br><span class=\"line\"> <span class=\"attribute\">float</span>: left;</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, skyblue , snow);</span><br><span class=\"line\"> <span class=\"attribute\">width</span>: <span class=\"number\">100px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">margin-left</span>: -<span class=\"number\">100%</span>;</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"selector-class\">.right</span> {</span><br><span class=\"line\"> <span class=\"attribute\">float</span>: left;</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, plum , snow);</span><br><span class=\"line\"> <span class=\"attribute\">width</span>: <span class=\"number\">120px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">margin-left</span>: -<span class=\"number\">120px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-tag\">footer</span> {</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, silver , snow);</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\"> <span class=\"attribute\">height</span>: <span class=\"number\">40px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">40px</span>;</span><br><span class=\"line\"> <span class=\"comment\">/* 清除浮动 */</span></span><br><span class=\"line\"> <span class=\"attribute\">clear</span>: both;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n</details>\n\n<hr>\n<h1 id=\"3-Flex布局\"><a href=\"#3-Flex布局\" class=\"headerlink\" title=\"3.Flex布局\"></a>3.Flex布局</h1><p>实现流程:</p>\n<ul>\n<li>设置header和footer,横向撑开</li>\n<li>container中的center,left,right依次排列</li>\n<li>给container设置弹性布局flex</li>\n<li>left,right设定固定宽度,center设置flex:1,宽度自适应</li>\n</ul>\n<iframe width=\"100%\" height=\"330\" src=\"//jsrun.net/V4wKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"HTML\"><figure class=\"iseeu highlight /html\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">class</span>=<span class=\"string\">"header"</span>></span>头部<span class=\"tag\"></<span class=\"name\">div</span>></span></span><br><span class=\"line\"><span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">class</span>=<span class=\"string\">"container"</span>></span></span><br><span class=\"line\"> <span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">class</span>=<span class=\"string\">"left"</span>></span>左区域<span class=\"tag\"></<span class=\"name\">div</span>></span></span><br><span class=\"line\"> <span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">class</span>=<span class=\"string\">"center"</span>></span>中间区域<span class=\"tag\"></<span class=\"name\">div</span>></span></span><br><span class=\"line\"> <span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">class</span>=<span class=\"string\">"right"</span>></span>右区域<span class=\"tag\"></<span class=\"name\">div</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\">div</span> <span class=\"attr\">class</span>=<span class=\"string\">"footer"</span>></span>底部<span class=\"tag\"></<span class=\"name\">div</span>></span></span><br></pre></td></tr></table></figure></div>\n\n<details>\n <summary>展开CSS样式</summary>\n <div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\">* {</span><br><span class=\"line\"> <span class=\"attribute\">margin</span>: <span class=\"number\">0</span>;</span><br><span class=\"line\"> <span class=\"attribute\">padding</span>: <span class=\"number\">0</span>;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.header</span> {</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, silver , snow);</span><br><span class=\"line\"> <span class=\"attribute\">width</span>: <span class=\"number\">100%</span>;</span><br><span class=\"line\"> <span class=\"attribute\">height</span>: <span class=\"number\">40px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">40px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: flex;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.center</span> {</span><br><span class=\"line\"> <span class=\"attribute\">flex</span>: <span class=\"number\">1</span>;</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, red , snow);</span><br><span class=\"line\"> <span class=\"attribute\">height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.left</span> {</span><br><span class=\"line\"> <span class=\"attribute\">width</span>: <span class=\"number\">80px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right,yellow , snow);</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.right</span> {</span><br><span class=\"line\"> <span class=\"attribute\">width</span>: <span class=\"number\">120px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, skyblue , snow);</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.footer</span> {</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, silver , snow);</span><br><span class=\"line\"> <span class=\"attribute\">width</span>: <span class=\"number\">100%</span>;</span><br><span class=\"line\"> <span class=\"attribute\">height</span>: <span class=\"number\">40px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">40px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n</details>\n\n<hr>\n<h1 id=\"4-Grid布局\"><a href=\"#4-Grid布局\" class=\"headerlink\" title=\"4.Grid布局\"></a>4.Grid布局</h1><p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/%E5%9C%A3%E6%9D%AF%E5%B8%83%E5%B1%80-grid.PNG\" alt=\"圣杯布局-Grid\"></p>\n<p>实现流程:</p>\n<ul>\n<li>给body添加display:grid属性</li>\n<li>因为center需要优先渲染,所以直接通过控制容器属性布局难以达到想要的效果</li>\n<li>我们通过控制容器中项目的左右网格线位置来间接达到center优先渲染的目的</li>\n<li>header设置grid-row: 1; 和 grid-column: 1/5; 第一行独占整列</li>\n<li>center设置grid-row: 2; 和 grid-column: 2/4; 第二行从第二条网格线开始到第四条网格线结束</li>\n<li>left设置grid-row: 2; 和 grid-column: 1/2; 第二行从第一条网格线开始到第二条网格线结束</li>\n<li>right设置grid-row: 2; 和 grid-column: 4/5; 第二行从第四条网格线开始到第五条网格线结束</li>\n<li>footer设置grid-row: 1; 和 grid-column: 1/5; 第三行从第一条网格线开始到第五条网格线结束</li>\n</ul>\n<iframe width=\"100%\" height=\"330\" src=\"//jsrun.net/e4wKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"HTML\"><figure class=\"iseeu highlight /html\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"tag\"><<span class=\"name\">header</span>></span>头部<span class=\"tag\"></<span class=\"name\">header</span>></span></span><br><span class=\"line\"><span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">class</span>=<span class=\"string\">"center"</span>></span>主区域<span class=\"tag\"></<span class=\"name\">div</span>></span></span><br><span class=\"line\"><span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">class</span>=<span class=\"string\">"left"</span>></span>左区域<span class=\"tag\"></<span class=\"name\">div</span>></span></span><br><span class=\"line\"><span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">class</span>=<span class=\"string\">"right"</span>></span>右区域<span class=\"tag\"></<span class=\"name\">div</span>></span></span><br><span class=\"line\"><span class=\"tag\"><<span class=\"name\">footer</span>></span>底部<span class=\"tag\"></<span class=\"name\">footer</span>></span></span><br></pre></td></tr></table></figure></div>\n\n<details>\n <summary>展开CSS样式</summary>\n <div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\">* {</span><br><span class=\"line\"> <span class=\"attribute\">margin</span>: <span class=\"number\">0</span>;</span><br><span class=\"line\"> <span class=\"attribute\">padding</span>: <span class=\"number\">0</span>;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-tag\">body</span> {</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-tag\">header</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-row</span>: <span class=\"number\">1</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-column</span>: <span class=\"number\">1</span>/<span class=\"number\">5</span>;</span><br><span class=\"line\"> <span class=\"attribute\">height</span>: <span class=\"number\">40px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">40px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, silver , snow);</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.center</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-row</span>: <span class=\"number\">2</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-column</span>: <span class=\"number\">2</span>/<span class=\"number\">4</span>;</span><br><span class=\"line\"> <span class=\"attribute\">height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, red , snow);</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.left</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-row</span>: <span class=\"number\">2</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-column</span>: <span class=\"number\">1</span>/<span class=\"number\">2</span>;</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, plum , snow);</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"selector-class\">.right</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-row</span>: <span class=\"number\">2</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-column</span>: <span class=\"number\">4</span>/<span class=\"number\">5</span>;</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">200px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, skyblue , snow);</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-tag\">footer</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-row</span>: <span class=\"number\">3</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-column</span>: <span class=\"number\">1</span>/<span class=\"number\">5</span>;</span><br><span class=\"line\"> <span class=\"attribute\">height</span>: <span class=\"number\">40px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">line-height</span>: <span class=\"number\">40px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">text-align</span>: center;</span><br><span class=\"line\"> <span class=\"attribute\">background-image</span>: <span class=\"built_in\">linear-gradient</span>(to right, silver , snow);</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n</details>\n\n<hr>\n","categories":["CSS"],"tags":["CSS","CSS布局"]},{"title":"DOM-仿PPT效果","url":"/2021/01/26/DOM-%E4%BB%BFPPT%E6%95%88%E6%9E%9C/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<iframe width=\"100%\" height=\"580\" src=\"//jsrun.net/uLaKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"DOM事件流","url":"/2021/01/03/DOM%E4%BA%8B%E4%BB%B6%E6%B5%81/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-什么是事件流?\"><a href=\"#1-什么是事件流?\" class=\"headerlink\" title=\"1.什么是事件流?\"></a>1.什么是事件流?</h1><p>HTML与js交互是通过事件驱动实现的,比如点击事件onclick,事件流描述了从页面中接收事件的顺序,包括三个阶段:</p>\n<ul>\n<li>捕获阶段</li>\n<li>目标阶段</li>\n<li>冒泡阶段</li>\n</ul>\n<p>addEventListener: 这个方法接收三个参数,要处理的事件名,事件处理函数和一个布尔值,这个布尔值参数如果是true,在事件捕获阶段调用事件处理函数,如果为false,则在事件冒泡阶段调用事件处理函数。</p>\n<p>捕获阶段执行顺序:document -> html -> body -> father -> son</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/ZnIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>冒泡阶段执行顺序:son -> father -> body -> html -> document</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/hnIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h1 id=\"2-阻止事件的默认行为\"><a href=\"#2-阻止事件的默认行为\" class=\"headerlink\" title=\"2.阻止事件的默认行为\"></a>2.阻止事件的默认行为</h1><p>preventDefault()</p>\n<iframe width=\"100%\" height=\"200\" src=\"//jsrun.net/XnIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h1 id=\"3-阻止事件冒泡\"><a href=\"#3-阻止事件冒泡\" class=\"headerlink\" title=\"3.阻止事件冒泡\"></a>3.阻止事件冒泡</h1><iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/WnIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h1 id=\"4-事件委托\"><a href=\"#4-事件委托\" class=\"headerlink\" title=\"4.事件委托\"></a>4.事件委托</h1><iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/fnIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"ES6-var,let,const的区别","url":"/2020/12/18/ES6-var-let-const%E7%9A%84%E5%8C%BA%E5%88%AB/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-不挂载到全局对象window\"><a href=\"#1-不挂载到全局对象window\" class=\"headerlink\" title=\"1.不挂载到全局对象window\"></a>1.不挂载到全局对象window</h1><p>var会把变量挂载到全局对象window上,这是js设计之初的缺陷之一,在ES6中引入了let和const可以解决这一历史遗留问题:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> a = <span class=\"number\">1</span></span><br><span class=\"line\"><span class=\"keyword\">let</span> b = <span class=\"number\">1</span></span><br><span class=\"line\"><span class=\"keyword\">const</span> c = <span class=\"number\">1</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"built_in\">window</span>.a) <span class=\"comment\">// 1</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"built_in\">window</span>.b) <span class=\"comment\">// undefined</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"built_in\">window</span>.c) <span class=\"comment\">// undefined</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"2-不允许重复声明\"><a href=\"#2-不允许重复声明\" class=\"headerlink\" title=\"2.不允许重复声明\"></a>2.不允许重复声明</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> a = <span class=\"number\">5</span>;</span><br><span class=\"line\"><span class=\"keyword\">let</span> a = <span class=\"number\">6</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(a);</span><br><span class=\"line\"><span class=\"comment\">// Uncaught SyntaxError: Identifier 'a' has already been declared</span></span><br></pre></td></tr></table></figure></div>\n\n<h1 id=\"3-不存在变量提升\"><a href=\"#3-不存在变量提升\" class=\"headerlink\" title=\"3.不存在变量提升\"></a>3.不存在变量提升</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(a); <span class=\"comment\">// undefined</span></span><br><span class=\"line\"><span class=\"keyword\">var</span> a = <span class=\"number\">1</span>;</span><br></pre></td></tr></table></figure></div>\n\n<p>上述代码中,还未声明变量a,却可以使用这个变量,原因是变量声明被提升了,上述代码可以等同看做下面这段代码:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> a</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(a); <span class=\"comment\">// undefined</span></span><br><span class=\"line\">a = <span class=\"number\">1</span>;</span><br></pre></td></tr></table></figure></div>\n\n<p>不仅var声明变量会提升,函数也会提升:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(a) <span class=\"comment\">// ƒ a() {}</span></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">a</span>(<span class=\"params\"></span>) </span>{}</span><br><span class=\"line\"><span class=\"keyword\">var</span> a = <span class=\"number\">1</span></span><br></pre></td></tr></table></figure></div>\n\n<p>我们可以看出,函数也会提升,而且函数提升优先于变量提升。</p>\n<p>let和const不存在变量提升,在声明前使用变量会报错:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(a) <span class=\"comment\">// undefined</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(b) <span class=\"comment\">// Uncaught ReferenceError: Cannot access 'b' before initialization</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(c) <span class=\"comment\">// Uncaught ReferenceError: Cannot access 'c' before initialization</span></span><br><span class=\"line\"><span class=\"keyword\">var</span> a = <span class=\"number\">1</span></span><br><span class=\"line\"><span class=\"keyword\">let</span> b = <span class=\"number\">1</span></span><br><span class=\"line\"><span class=\"keyword\">const</span> c = <span class=\"number\">1</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"4-暂时性死区\"><a href=\"#4-暂时性死区\" class=\"headerlink\" title=\"4.暂时性死区\"></a>4.暂时性死区</h1><p>在es6中引入了块级作用域的概念,{}产生块级作用域,if和for中的{}也是块级作用域</p>\n<p>var没有块级作用域:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">if</span>(<span class=\"literal\">false</span>){</span><br><span class=\"line\"> <span class=\"keyword\">var</span> a = <span class=\"number\">5</span></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(a); <span class=\"comment\">// undefined</span></span><br></pre></td></tr></table></figure></div>\n\n<p>if和for都会产生块级作用域</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">for</span> (<span class=\"keyword\">var</span> i = <span class=\"number\">0</span>; i < <span class=\"number\">3</span>; i++){</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(i); <span class=\"comment\">// 0, 1, 2</span></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(i); <span class=\"comment\">// 3</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">for</span> (<span class=\"keyword\">let</span> i = <span class=\"number\">0</span>; i < <span class=\"number\">3</span>; i++){</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(i); <span class=\"comment\">// 0, 1, 2</span></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(i); <span class=\"comment\">// 报错</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> a = <span class=\"number\">5</span></span><br><span class=\"line\"><span class=\"keyword\">if</span>(<span class=\"literal\">true</span>){</span><br><span class=\"line\"> a = <span class=\"number\">5</span></span><br><span class=\"line\"> <span class=\"keyword\">let</span> a</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"comment\">// Uncaught ReferenceError: Cannot access 'a' before initialization</span></span><br></pre></td></tr></table></figure></div>\n\n<p>如果块级作用域中存在let命令,它所声明的变量就绑定在这个区域,不会再受外部作用域的干扰。</p>\n<p>上述代码中由于if产生块级作用域中,所以let绑定了该作用域,全局变量中a变量访问这块作用域受限制,因此在let声明之前,对a变量赋值会报错。</p>\n<p>一句话概括,暂时性死区就是变量在创建后还未初始化就被使用</p>\n<p>有一些暂时性死区比较隐蔽,不容易发现:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">let</span> x = y; <span class=\"comment\">// Uncaught ReferenceError: Cannot access 'y' before initialization</span></span><br><span class=\"line\"> <span class=\"keyword\">let</span> y = <span class=\"number\">2</span>;</span><br><span class=\"line\">}</span><br><span class=\"line\">test()</span><br></pre></td></tr></table></figure></div>\n\n<p>x = y 的复制过程发生时,y还未被声明,因此产生了暂时性死区。</p>\n<hr>\n<h1 id=\"5-块级作用域的经典面试题\"><a href=\"#5-块级作用域的经典面试题\" class=\"headerlink\" title=\"5.块级作用域的经典面试题\"></a>5.块级作用域的经典面试题</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// setTimeout -> 异步操作 for循环执行完成后执行3次</span></span><br><span class=\"line\"><span class=\"keyword\">for</span> (<span class=\"keyword\">var</span> i = <span class=\"number\">0</span>; i < <span class=\"number\">3</span>; i++){</span><br><span class=\"line\"> <span class=\"built_in\">setTimeout</span>(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(i) <span class=\"comment\">// 3, 3, 3</span></span><br><span class=\"line\"> })</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 1.闭包 立即执行函数</span></span><br><span class=\"line\"><span class=\"keyword\">for</span> (<span class=\"keyword\">var</span> i = <span class=\"number\">0</span>; i < <span class=\"number\">3</span>; i++){</span><br><span class=\"line\"> (<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">j</span>)</span>{</span><br><span class=\"line\"> <span class=\"built_in\">setTimeout</span>(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>)</span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(j) <span class=\"comment\">// 0, 1, 2</span></span><br><span class=\"line\"> })</span><br><span class=\"line\"> })(i)</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 2.let 块级作用域</span></span><br><span class=\"line\"><span class=\"keyword\">for</span> (<span class=\"keyword\">let</span> i = <span class=\"number\">0</span>; i < <span class=\"number\">3</span>; i++){</span><br><span class=\"line\"> <span class=\"built_in\">setTimeout</span>(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(i) <span class=\"comment\">// 0, 1, 2</span></span><br><span class=\"line\"> })</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>那么这段代码究竟发生了什么?</p>\n<p>可以通过<a href=\"https://www.babeljs.cn/\">Babel</a>将es6语法转化为我们所熟悉的es5:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"meta\">"use strict"</span>;</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">var</span> _loop = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">_loop</span>(<span class=\"params\">i</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">setTimeout</span>(<span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(i);</span><br><span class=\"line\"> });</span><br><span class=\"line\">};</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">for</span> (<span class=\"keyword\">var</span> i = <span class=\"number\">0</span>; i < <span class=\"number\">3</span>; i++) {</span><br><span class=\"line\"> _loop(i);</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<blockquote>\n<p>不难看出,let和闭包两种方法的实现原理基本一致</p>\n</blockquote>\n<hr>\n<h1 id=\"6-const\"><a href=\"#6-const\" class=\"headerlink\" title=\"6.const\"></a>6.const</h1><p>let和const的作用基本一致,区别是const声明的变量为常量,值不能改变。</p>\n<p>es5中定义常量的方法:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">Object</span>.defineProperty(<span class=\"built_in\">window</span>, <span class=\"string\">'PI'</span>, {</span><br><span class=\"line\"> value: <span class=\"number\">3.14</span>,</span><br><span class=\"line\"> writable: <span class=\"literal\">false</span></span><br><span class=\"line\">})</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(PI) <span class=\"comment\">// 3.14</span></span><br><span class=\"line\">PI = <span class=\"number\">5</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(PI) <span class=\"comment\">// 3.14</span></span><br></pre></td></tr></table></figure></div>\n\n<p>es6:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> a = <span class=\"number\">5</span>;</span><br><span class=\"line\">a = <span class=\"string\">'123'</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(b) <span class=\"comment\">// Uncaught TypeError: Assignment to constant variable</span></span><br></pre></td></tr></table></figure></div>\n\n<p>const的值并非是不能改变的</p>\n<p>对于引用类型值来说,变量中保存的只是对象的引用地址,更改对象属性不会影响指针指向。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> obj = {};</span><br><span class=\"line\">obj.name = <span class=\"string\">'CalDey'</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj); <span class=\"comment\">// {name: "CalDey"}</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>];</span><br><span class=\"line\">arr.push(<span class=\"number\">4</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr); <span class=\"comment\">// [1, 2, 3, 4]</span></span><br></pre></td></tr></table></figure></div>\n\n<p>如果想要固定引用类型值,可以使用Object.freeze(),但要注意该方法为浅冻结</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> obj = {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span>,</span><br><span class=\"line\"> age: <span class=\"number\">23</span>,</span><br><span class=\"line\"> hello: {</span><br><span class=\"line\"> say: <span class=\"string\">'hello'</span></span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"built_in\">Object</span>.freeze(obj);</span><br><span class=\"line\"><span class=\"built_in\">Object</span>.freeze(obj.hello);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj);</span><br><span class=\"line\">obj.say = <span class=\"string\">'helloworld'</span>;</span><br><span class=\"line\">obj.hello.say = <span class=\"string\">'helloworld'</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj.say); <span class=\"comment\">// undefined</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"4-总结\"><a href=\"#4-总结\" class=\"headerlink\" title=\"4.总结\"></a>4.总结</h1><ul>\n<li>1.不挂载到全局对象window</li>\n<li>2.不允许重复声明</li>\n<li>3.不存在变量提升</li>\n<li>4.暂时性死区</li>\n<li>5.块级作用域</li>\n</ul>\n<hr>\n<blockquote>\n<p>内容参考自:<br><a href=\"https://juejin.cn/book/6844733763675488269/section/6844733763759374344\">前端面试之道</a><br><a href=\"https://blog.csdn.net/ganlubaba666/article/details/89792643\">理解es6中的暂时性死区</a><br><a href=\"http://es.xiecheng.live/\">ECMAScript2015~2020语法全解析</a></p>\n</blockquote>\n","categories":["JavaScript","ES6"],"tags":["JavaScript","ES6"]},{"title":"ES6-原型继承和class继承","url":"/2020/12/18/ES6-%E5%8E%9F%E5%9E%8B%E7%BB%A7%E6%89%BF%E5%92%8Cclass%E7%BB%A7%E6%89%BF/","content":"<p>原型如何实现继承?Class 如何实现继承?Class 本质是什么?</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-ES5-继承\"><a href=\"#1-ES5-继承\" class=\"headerlink\" title=\"1.ES5-继承\"></a>1.ES5-继承</h1><h2 id=\"1-1-原型链继承\"><a href=\"#1-1-原型链继承\" class=\"headerlink\" title=\"1.1.原型链继承\"></a>1.1.原型链继承</h2><p>有关原型链的内容请参考<a href=\"/2020/12/16/JavaScript-%E8%BD%BB%E6%9D%BE%E7%90%86%E8%A7%A3%E5%8E%9F%E5%9E%8B%E5%92%8C%E5%8E%9F%E5%9E%8B%E9%93%BE/\" title=\"JavaScript-轻松理解原型和原型链\">JavaScript-轻松理解原型和原型链</a></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Animal</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.name = <span class=\"string\">'lucky'</span>;</span><br><span class=\"line\">}</span><br><span class=\"line\">Animal.prototype.getName = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name)</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Cat</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"></span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\">Cat.prototype = <span class=\"keyword\">new</span> Animal();</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">var</span> cat = <span class=\"keyword\">new</span> Cat();</span><br><span class=\"line\">cat.getName(); <span class=\"comment\">// lucky</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(cat <span class=\"keyword\">instanceof</span> Cat); <span class=\"comment\">// true</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(cat <span class=\"keyword\">instanceof</span> Animal); <span class=\"comment\">// true</span></span><br><span class=\"line\"><span class=\"keyword\">var</span> cat2 = <span class=\"keyword\">new</span> Cat();</span><br><span class=\"line\">cat2.getName(); <span class=\"comment\">// lucky</span></span><br></pre></td></tr></table></figure></div>\n\n<p>如果属性中有引用类型,则会被所有实例共享:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Animal</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"><span class=\"built_in\">this</span>.name = [<span class=\"string\">'Lucky'</span>, <span class=\"string\">'Thomas'</span>];</span><br><span class=\"line\">}</span><br><span class=\"line\">Animal.prototype.getName = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name)</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Cat</span>(<span class=\"params\"></span>) </span>{}</span><br><span class=\"line\"></span><br><span class=\"line\">Cat.prototype = <span class=\"keyword\">new</span> Animal();</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> cat1 = <span class=\"keyword\">new</span> Cat();</span><br><span class=\"line\">cat1.getName(); <span class=\"comment\">// ["Lucky","Thomas"]</span></span><br><span class=\"line\"><span class=\"keyword\">const</span> cat2 = <span class=\"keyword\">new</span> Cat();</span><br><span class=\"line\">cat2.name.reverse();</span><br><span class=\"line\">cat1.getName(); <span class=\"comment\">// ["Thomas","Lucky"]</span></span><br><span class=\"line\">cat2.getName(); <span class=\"comment\">// ["Thomas","Lucky"]</span></span><br></pre></td></tr></table></figure></div>\n\n<p>同时,创建子类型实例时,不能向父类型中传递参数(原型链)</p>\n<p>在实践中一般很少单独使用原型链继承</p>\n<hr>\n<h2 id=\"1-2-借用构造函数(经典继承)\"><a href=\"#1-2-借用构造函数(经典继承)\" class=\"headerlink\" title=\"1.2.借用构造函数(经典继承)\"></a>1.2.借用构造函数(经典继承)</h2><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Animal</span>(<span class=\"params\">name</span>) </span>{</span><br><span class=\"line\"><span class=\"built_in\">this</span>.name = name</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Cat</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\">Animal.call(<span class=\"built_in\">this</span>)</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> cat1 = <span class=\"keyword\">new</span> Cat();</span><br><span class=\"line\"><span class=\"keyword\">const</span> cat2 = <span class=\"keyword\">new</span> Cat();</span><br><span class=\"line\">cat1.name = <span class=\"string\">'Lucky'</span></span><br><span class=\"line\">cat2.name = <span class=\"string\">'Thomas'</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(cat1.name,cat2.name)</span><br></pre></td></tr></table></figure></div>\n\n<p>优点:</p>\n<p>1.避免了引用类型的属性被所有实例共享</p>\n<p>2.可以向父级传参</p>\n<p>缺点:</p>\n<p>每次创建新的实例对象都要重新定义一次属性和方法</p>\n<hr>\n<h2 id=\"1-3-组合继承\"><a href=\"#1-3-组合继承\" class=\"headerlink\" title=\"1.3.组合继承\"></a>1.3.组合继承</h2><p>组合继承是最常用的继承方式,原型链继承和经典继承双剑合璧:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Animal</span>(<span class=\"params\">name</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.name = name;</span><br><span class=\"line\">}</span><br><span class=\"line\">Animal.prototype.getName = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name);</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Cat</span>(<span class=\"params\">name, action</span>) </span>{</span><br><span class=\"line\"> Animal.call(<span class=\"built_in\">this</span>, name);</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.action = action;</span><br><span class=\"line\">}</span><br><span class=\"line\">Cat.prototype = <span class=\"keyword\">new</span> Animal()</span><br><span class=\"line\"><span class=\"keyword\">let</span> cat1 = <span class=\"keyword\">new</span> Cat(<span class=\"string\">'lucky'</span>, <span class=\"string\">'run'</span>);</span><br><span class=\"line\">cat1.getName(); <span class=\"comment\">// lucky</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(cat1.name, cat1.action); <span class=\"comment\">// lucky, run</span></span><br><span class=\"line\"><span class=\"keyword\">let</span> cat2 = <span class=\"keyword\">new</span> Cat(<span class=\"string\">'Tom'</span>, <span class=\"string\">'sleep'</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(cat2.name, cat2.action); <span class=\"comment\">// Tom, sleep</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(cat1 <span class=\"keyword\">instanceof</span> Animal) <span class=\"comment\">// true</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(cat1)</span><br></pre></td></tr></table></figure></div>\n\n<p>这种继承方式的优点在于构造函数可以传参,不会共享父类引用类型属性,可以复用父类函数。但这种继承方式并不完美,最大的缺点就是调用了两次父类构造函数,导致子类的原型上多了不必要的父类属性,存在内存上的浪费:</p>\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/202102201724.PNG\"></p>\n<p>为了避免重复调用,是否可以不直接使用Cat.prototype = new Animal(),而是间接让Cat.prototype访问到Animal.prototype呢?</p>\n<hr>\n<h2 id=\"1-4-寄生组合继承(圣杯模式)\"><a href=\"#1-4-寄生组合继承(圣杯模式)\" class=\"headerlink\" title=\"1.4.寄生组合继承(圣杯模式)\"></a>1.4.寄生组合继承(圣杯模式)</h2><p>我们对代码进行改进:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Animal</span>(<span class=\"params\">name</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.name = name;</span><br><span class=\"line\">}</span><br><span class=\"line\">Animal.prototype.getName = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name);</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Cat</span>(<span class=\"params\">name, action</span>) </span>{</span><br><span class=\"line\"> Animal.call(<span class=\"built_in\">this</span>, name);</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.action = action;</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"comment\">// Cat.prototype = new Animal()</span></span><br><span class=\"line\"><span class=\"comment\">// 关键3步</span></span><br><span class=\"line\"><span class=\"keyword\">let</span> Buffer = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{};</span><br><span class=\"line\">Buffer.prototype = Animal.prototype;</span><br><span class=\"line\">Cat.prototype = <span class=\"keyword\">new</span> Buffer();</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">let</span> cat = <span class=\"keyword\">new</span> Cat(<span class=\"string\">'lucky'</span>, <span class=\"string\">'run'</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(cat.name, cat.action); <span class=\"comment\">// lucky, run</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(cat)</span><br></pre></td></tr></table></figure></div>\n\n<p>通过借助函数BUffer作为中间件间接链接父类和子类,使子类可以继承父类的原型,且可以自定义属性,并且不会在原型上重复继承父类属性</p>\n<hr>\n<h1 id=\"2-ES6-Class继承\"><a href=\"#2-ES6-Class继承\" class=\"headerlink\" title=\"2.ES6-Class继承\"></a>2.ES6-Class继承</h1><p>以上继承方法都是通过原型解决的,在ES6中,我们可以通过Class来实现继承:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 父类</span></span><br><span class=\"line\"><span class=\"class\"><span class=\"keyword\">class</span> <span class=\"title\">People</span> </span>{</span><br><span class=\"line\"> <span class=\"function\"><span class=\"title\">constructor</span>(<span class=\"params\">name</span>)</span>{</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=\"function\"><span class=\"title\">eat</span>(<span class=\"params\"></span>)</span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(</span><br><span class=\"line\"> <span class=\"string\">`<span class=\"subst\">${<span class=\"built_in\">this</span>.name}</span> eat something`</span></span><br><span class=\"line\"> )</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"comment\">// 子类</span></span><br><span class=\"line\"><span class=\"class\"><span class=\"keyword\">class</span> <span class=\"title\">Child</span> <span class=\"keyword\">extends</span> <span class=\"title\">People</span> </span>{</span><br><span class=\"line\"> <span class=\"function\"><span class=\"title\">constructor</span>(<span class=\"params\">name, action</span>)</span>{</span><br><span class=\"line\"> <span class=\"built_in\">super</span>(name);</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.action = action;</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> person = <span class=\"keyword\">new</span> Child(<span class=\"string\">'CalDey'</span>, <span class=\"string\">'run'</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(person.name) <span class=\"comment\">// CalDey</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(person.action) <span class=\"comment\">// run</span></span><br><span class=\"line\">person.eat() <span class=\"comment\">// CalDey eat something</span></span><br></pre></td></tr></table></figure></div>\n\n<p>Class的核心在于使用extends表面继承自哪个父类,在子类构造函数中必须调用super,其作用相当于call()</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"class\"><span class=\"keyword\">class</span> <span class=\"title\">Animal</span> </span>{</span><br><span class=\"line\"> <span class=\"function\"><span class=\"title\">constructor</span>(<span class=\"params\">name</span>)</span> {</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.name = name;</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"class\"><span class=\"keyword\">class</span> <span class=\"title\">Cat</span> <span class=\"keyword\">extends</span> <span class=\"title\">Animal</span> </span>{</span><br><span class=\"line\"> <span class=\"function\"><span class=\"title\">constructor</span>(<span class=\"params\">name, eat</span>)</span> {</span><br><span class=\"line\"> <span class=\"built_in\">super</span>(name);</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.eat = eat;</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"function\"><span class=\"title\">action</span>(<span class=\"params\"></span>)</span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">`<span class=\"subst\">${<span class=\"built_in\">this</span>.name}</span> eating <span class=\"subst\">${<span class=\"built_in\">this</span>.eat}</span>`</span>);</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">const</span> cat = <span class=\"keyword\">new</span> Cat(<span class=\"string\">'Lucky'</span>, <span class=\"string\">'meat'</span>);</span><br><span class=\"line\">cat.action(); <span class=\"comment\">// Lucky eating meat</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(cat <span class=\"keyword\">instanceof</span> Cat); <span class=\"comment\">// true</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(cat <span class=\"keyword\">instanceof</span> Animal); <span class=\"comment\">// true</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(cat <span class=\"keyword\">instanceof</span> <span class=\"built_in\">Object</span>); <span class=\"comment\">// true</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"keyword\">typeof</span> Cat); <span class=\"comment\">// function</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"keyword\">typeof</span> Animal); <span class=\"comment\">// function</span></span><br></pre></td></tr></table></figure></div>\n\n<blockquote>\n<p>再次强调,JS中并不存在类,Class是语法糖,本质仍是函数。</p>\n</blockquote>\n<hr>\n<blockquote>\n<p>内容参考自:<br><a href=\"https://juejin.cn/book/6844733763675488269/section/6844733763759374344\">前端面试之道</a><br><a href=\"https://github.com/mqyqingfeng/Blog/issues/16\">JavaScript深入之继承的多种方式和优缺点</a></p>\n</blockquote>\n","categories":["JavaScript","ES6"],"tags":["JavaScript","ES6"]},{"title":"Flex-六面骰子","url":"/2021/02/03/Flex-%E5%85%AD%E9%9D%A2%E9%AA%B0%E5%AD%90/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<p>通过flex布局实现六面骰子</p>\n<iframe width=\"100%\" height=\"350\" src=\"//jsrun.net/3eaKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<iframe width=\"100%\" height=\"350\" src=\"//jsrun.net/VeaKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<iframe width=\"100%\" height=\"350\" src=\"//jsrun.net/9eaKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<iframe width=\"100%\" height=\"350\" src=\"//jsrun.net/eeaKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<iframe width=\"100%\" height=\"350\" src=\"//jsrun.net/EeaKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<iframe width=\"100%\" height=\"350\" src=\"//jsrun.net/seaKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n","categories":["CSS"],"tags":["CSS","CSS布局"]},{"title":"Hexo markdown语法","url":"/2020/12/03/Hexo%20markdown%E8%AF%AD%E6%B3%95/","content":"<p>这是一篇Markdown语法测试文章,随便写点啥吧~</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"列表\"><a href=\"#列表\" class=\"headerlink\" title=\"列表\"></a>列表</h1><ul>\n<li><p>列表1</p>\n</li>\n<li><p>列表2<br> a 子列表<br> b 子列表</p>\n</li>\n<li><p>列表3</p>\n</li>\n</ul>\n<hr>\n<!-- more -->\n\n<h1 id=\"表格\"><a href=\"#表格\" class=\"headerlink\" title=\"表格\"></a>表格</h1><table>\n<thead>\n<tr>\n<th align=\"center\">HTML</th>\n<th align=\"center\">CSS</th>\n<th align=\"center\">JS</th>\n</tr>\n</thead>\n<tbody><tr>\n<td align=\"center\">内容</td>\n<td align=\"center\">内容</td>\n<td align=\"center\">内容</td>\n</tr>\n<tr>\n<td align=\"center\">内容</td>\n<td align=\"center\">内容</td>\n<td align=\"center\">内容</td>\n</tr>\n</tbody></table>\n<h1 id=\"超文本链接\"><a href=\"#超文本链接\" class=\"headerlink\" title=\"超文本链接\"></a>超文本链接</h1><p><a href=\"https://www.baidu.com/\">百度</a></p>\n<h1 id=\"Image\"><a href=\"#Image\" class=\"headerlink\" title=\"Image\"></a>Image</h1><p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20201202195621.jpg\" alt=\"我的avatar\"></p>\n<h1 id=\"文本处理\"><a href=\"#文本处理\" class=\"headerlink\" title=\"文本处理\"></a>文本处理</h1><p><em>倾斜</em><br><strong>加粗</strong><br><strong><em>倾斜加粗</em></strong><br><del>你知道的太多了</del></p>\n<h1 id=\"代码块\"><a href=\"#代码块\" class=\"headerlink\" title=\"代码块\"></a>代码块</h1><p><code><html></html></code></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"HTML\"><figure class=\"iseeu highlight /html\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"tag\"><<span class=\"name\">html</span>></span></span><br><span class=\"line\"> <span class=\"tag\"><<span class=\"name\">header</span>></span>我是标题<span class=\"tag\"></<span class=\"name\">header</span>></span></span><br><span class=\"line\"> <span class=\"tag\"><<span class=\"name\">div</span>></span>我是内容<span class=\"tag\"></<span class=\"name\">div</span>></span></span><br><span class=\"line\"> <span class=\"tag\"><<span class=\"name\">footer</span>></span>我是footer<span class=\"tag\"></<span class=\"name\">footer</span>></span></span><br><span class=\"line\"><span class=\"tag\"></<span class=\"name\">html</span>></span></span><br></pre></td></tr></table></figure></div>\n\n<h1 id=\"内容引用\"><a href=\"#内容引用\" class=\"headerlink\" title=\"内容引用\"></a>内容引用</h1><blockquote>\n<p>我是内容引用~</p>\n</blockquote>\n","categories":["Markdown"],"tags":["Markdown"]},{"title":"ES6-数组遍历方法","url":"/2021/02/02/ES6-%E6%95%B0%E7%BB%84%E9%81%8D%E5%8E%86%E6%96%B9%E6%B3%95/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"ES6中的数组遍历方法\"><a href=\"#ES6中的数组遍历方法\" class=\"headerlink\" title=\"ES6中的数组遍历方法\"></a>ES6中的数组遍历方法</h1><h2 id=\"1-find\"><a href=\"#1-find\" class=\"headerlink\" title=\"1.find()\"></a>1.find()</h2><p>返回通过筛选的第一个元素的值</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">arr = [<span class=\"number\">0</span>, <span class=\"number\">1</span>, <span class=\"number\">3</span>, <span class=\"number\">4</span>, <span class=\"number\">5</span>]</span><br><span class=\"line\"><span class=\"keyword\">let</span> res = arr.find(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">elem</span>)</span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> elem > <span class=\"number\">2</span></span><br><span class=\"line\">})</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [0, 1, 3, 4, 5]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(res) <span class=\"comment\">// 3</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"2-findIndex\"><a href=\"#2-findIndex\" class=\"headerlink\" title=\"2.findIndex()\"></a>2.findIndex()</h2><p>返回通过筛选的第一个元素的索引</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">arr = [<span class=\"number\">0</span>, <span class=\"number\">1</span>, <span class=\"number\">3</span>, <span class=\"number\">4</span>, <span class=\"number\">5</span>]</span><br><span class=\"line\"><span class=\"keyword\">let</span> res = arr.findIndex(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">elem</span>)</span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> elem > <span class=\"number\">2</span></span><br><span class=\"line\">})</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [0, 1, 3, 4, 5]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(res) <span class=\"comment\">// 2</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"3-for-…-of\"><a href=\"#3-for-…-of\" class=\"headerlink\" title=\"3.for … of\"></a>3.for … of</h2><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>]</span><br><span class=\"line\"><span class=\"keyword\">for</span>(<span class=\"keyword\">let</span> i <span class=\"keyword\">of</span> arr){</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(i) <span class=\"comment\">// 1, 2, 3</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>values() 值 -> 元素值</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>]</span><br><span class=\"line\"><span class=\"keyword\">for</span>(<span class=\"keyword\">let</span> i <span class=\"keyword\">of</span> arr.values()){</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(i) <span class=\"comment\">// 1, 2, 3</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>keys() 键 -> 索引</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>]</span><br><span class=\"line\"><span class=\"keyword\">for</span>(<span class=\"keyword\">let</span> i <span class=\"keyword\">of</span> arr.keys()){</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(i) <span class=\"comment\">// 0, 1, 2</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>entries() 创建一个可迭代对象,这个对象包含数组的键值对</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>]</span><br><span class=\"line\"><span class=\"keyword\">for</span>(<span class=\"keyword\">let</span> [index, item] <span class=\"keyword\">of</span> arr.entries()){</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(index, item) <span class=\"comment\">// 0 1 1 2 2 3</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<blockquote>\n<p>内容参考自:<a href=\"http://es.xiecheng.live/\">ECMAScript2015~2020语法全解析</a></p>\n</blockquote>\n","categories":["JavaScript","ES6"],"tags":["JavaScript","ES6"]},{"title":"JavaSciprt-手写call,apply,bind","url":"/2021/02/20/JavaSciprt-%E6%89%8B%E5%86%99call%EF%BC%8Capply%EF%BC%8Cbind/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-call\"><a href=\"#1-call\" class=\"headerlink\" title=\"1.call\"></a>1.call</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">Function</span>.prototype.myCall = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">t, ...args</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">const</span> _self = <span class=\"built_in\">this</span></span><br><span class=\"line\"> <span class=\"keyword\">return</span> (<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> _self.apply(t, args)</span><br><span class=\"line\"> })()</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">fn1</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>);</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a, b)</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\">fn2 = fn1.myCall({<span class=\"attr\">x</span>:<span class=\"number\">100</span>},<span class=\"number\">10</span>,<span class=\"number\">20</span>)</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"2-apply\"><a href=\"#2-apply\" class=\"headerlink\" title=\"2.apply\"></a>2.apply</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">Function</span>.prototype.myApply = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">t, args</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">const</span> _self = <span class=\"built_in\">this</span></span><br><span class=\"line\"> <span class=\"keyword\">return</span> (<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(...args)</span><br><span class=\"line\"> <span class=\"keyword\">return</span> _self.call(t, ...args)</span><br><span class=\"line\"> })()</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">fn1</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>);</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a, b)</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\">fn2 = fn1.myApply({<span class=\"attr\">x</span>:<span class=\"number\">100</span>},[<span class=\"number\">10</span>,<span class=\"number\">20</span>])</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"3-bind\"><a href=\"#3-bind\" class=\"headerlink\" title=\"3.bind\"></a>3.bind</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">Function</span>.prototype.myBind = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">const</span> args = <span class=\"built_in\">Array</span>.prototype.slice.call(<span class=\"built_in\">arguments</span>)</span><br><span class=\"line\"> <span class=\"keyword\">const</span> t = args.shift()</span><br><span class=\"line\"> <span class=\"keyword\">const</span> _this = <span class=\"built_in\">this</span></span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> _this.apply(t,args)</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">fn1</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>);</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a, b)</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> fn2 = fn1.myBind({<span class=\"attr\">x</span>:<span class=\"number\">100</span>},<span class=\"number\">10</span>,<span class=\"number\">20</span>)</span><br><span class=\"line\">fn2()</span><br></pre></td></tr></table></figure></div>","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScipt-Ajax","url":"/2021/02/21/JavaScipt-Ajax/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-什么是Ajax?\"><a href=\"#1-什么是Ajax?\" class=\"headerlink\" title=\"1.什么是Ajax?\"></a>1.什么是Ajax?</h1><p>Ajax是异步JavaScript和XML的简写</p>\n<p>Ajax可以异步向服务器发送请求,在等待响应的过程中,不会阻塞当前页面,在成功获取响应后,浏览器再处理相应数据</p>\n<p>XML(可扩展标记语言)是前后端数据通信时传输数据的一种格式,现在比较常用JSON</p>\n<p>Ajax其实就是浏览器和服务器之间的一种异步通信方式</p>\n<p>使用Ajax可以在不重新加载整个页面的情况下,对页面的某部分进行更新</p>\n<ul>\n<li>注册检测</li>\n<li>搜索提示</li>\n</ul>\n<hr>\n<h1 id=\"2-快速搭建Ajax开发环境\"><a href=\"#2-快速搭建Ajax开发环境\" class=\"headerlink\" title=\"2.快速搭建Ajax开发环境\"></a>2.快速搭建Ajax开发环境</h1><p>Ajax需要服务器环境才能正常运行</p>\n<p>通过 VSCode插件:live Server -> Open with Live Server 快速开启开发环境</p>\n<p>其他的快速搭建开发环境方法:</p>\n<p>Windows: XAMPP<br>Mac:MAMP</p>\n<hr>\n<h1 id=\"3-Ajax的基本使用\"><a href=\"#3-Ajax的基本使用\" class=\"headerlink\" title=\"3.Ajax的基本使用\"></a>3.Ajax的基本使用</h1><p>Ajax如果想要实现浏览器和服务器之间的数据通讯,需要依靠XMLHttpRequest,它是一个构造函数</p>\n<p>Ajax的使用步骤:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 1.创建xhr对象</span></span><br><span class=\"line\"><span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest();</span><br><span class=\"line\"><span class=\"comment\">// 2.发送请求前准备</span></span><br><span class=\"line\">xhr.open(<span class=\"string\">'HTTP请求'</span>) <span class=\"comment\">// 'HTTP请求(GET POST PUT DELETE)', 'url', 'true'(异步)</span></span><br><span class=\"line\"><span class=\"comment\">// 3.发送请求</span></span><br><span class=\"line\">xhr.send(); <span class=\"comment\">// 通过请求体携带数据(POST)</span></span><br><span class=\"line\"><span class=\"comment\">// 4.监听事件,处理响应</span></span><br><span class=\"line\"><span class=\"comment\">// onreadystatechange 监听状态变化</span></span><br><span class=\"line\">xhr.onreadystatechange = <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (xhr.readyState !== <span class=\"number\">4</span>) <span class=\"keyword\">return</span>;</span><br><span class=\"line\"> <span class=\"comment\">// 判断能否正常使用数据</span></span><br><span class=\"line\"> <span class=\"keyword\">if</span> ((xhr.status >= <span class=\"number\">200</span> && xhr.status < <span class=\"number\">300</span>) ||</span><br><span class=\"line\"> (xhr.status = <span class=\"number\">304</span>)) {</span><br><span class=\"line\"> <span class=\"comment\">// console.log('正常使用响应数据')</span></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(xhr.responseText)</span><br><span class=\"line\"> }</span><br><span class=\"line\">};</span><br></pre></td></tr></table></figure></div>\n\n<p>xhr.readyState</p>\n<p>0 -> 未初始化:还没有调用open()<br>1 -> 启动:已调用open()方法,但尚未调用send()<br>2 -> 发送:已调用send()方法,但尚未接收到响应<br>3 -> 接收:已接收到部分响应数据<br>4 -> 完成:已接收到全部响应数据</p>\n<hr>\n<h1 id=\"4-GET\"><a href=\"#4-GET\" class=\"headerlink\" title=\"4.GET\"></a>4.GET</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> url = <span class=\"string\">'https://www.imooc.com/api/http/search/suggest?words=js&username=CalDey&age=18'</span></span><br><span class=\"line\"><span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest()</span><br><span class=\"line\">xhr.open(<span class=\"string\">'GET'</span>, url, <span class=\"literal\">true</span>)</span><br><span class=\"line\">xhr.onreadystatechange = <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(xhr.readyState === <span class=\"number\">4</span>) {</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(xhr.status === <span class=\"number\">200</span>) {</span><br><span class=\"line\"> <span class=\"comment\">// response 可以替代responseText(不考虑兼容性情况下)</span></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">JSON</span>.parse(xhr.responseText))</span><br><span class=\"line\"> }<span class=\"keyword\">else</span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'err'</span>)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\">xhr.send(<span class=\"literal\">null</span>)</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"5-POST\"><a href=\"#5-POST\" class=\"headerlink\" title=\"5.POST\"></a>5.POST</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> url = <span class=\"string\">'https://www.imooc.com/api/http/search/suggest?words=js'</span></span><br><span class=\"line\"><span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest()</span><br><span class=\"line\">xhr.open(<span class=\"string\">'POST'</span>, url, <span class=\"literal\">true</span>)</span><br><span class=\"line\">xhr.onreadystatechange = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(xhr.readyState === <span class=\"number\">4</span>) {</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(xhr.status === <span class=\"number\">200</span>) {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">JSON</span>.parse(xhr.responseText))</span><br><span class=\"line\"> }<span class=\"keyword\">else</span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'err'</span>)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">const</span> postData = {</span><br><span class=\"line\"> userName: <span class=\"string\">'CalDey'</span>,</span><br><span class=\"line\"> password: <span class=\"number\">123456</span></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"comment\">// 不能直接传递对象,需要先将对象转化成字符串</span></span><br><span class=\"line\">xhr.send(<span class=\"built_in\">JSON</span>.stringify(postData))</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"6-xhr属性\"><a href=\"#6-xhr属性\" class=\"headerlink\" title=\"6.xhr属性\"></a>6.xhr属性</h1><h1 id=\"6-1-xhr-timeout\"><a href=\"#6-1-xhr-timeout\" class=\"headerlink\" title=\"6.1.xhr.timeout\"></a>6.1.xhr.timeout</h1><p>有时候一些请求因为网络原因不能及时得到响应,需要给用户一个提示增加用户体验</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">xhr.timeout = <span class=\"number\">10000</span> <span class=\"comment\">// 请求10s后超时会被取消</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"6-2-xhr-withCredentials\"><a href=\"#6-2-xhr-withCredentials\" class=\"headerlink\" title=\"6.2.xhr.withCredentials\"></a>6.2.xhr.withCredentials</h1><p>发送Ajax请求时是否携带Cookie</p>\n<p>默认情况下,同源会自动携带Cookie,跨域时不会</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">xhr.withCredentials = <span class=\"literal\">true</span> <span class=\"comment\">// 存在安全问题,能否成功需要服务器设置</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"7-xhr方法\"><a href=\"#7-xhr方法\" class=\"headerlink\" title=\"7.xhr方法\"></a>7.xhr方法</h1><h2 id=\"7-1-xhr-abort\"><a href=\"#7-1-xhr-abort\" class=\"headerlink\" title=\"7.1.xhr.abort()\"></a>7.1.xhr.abort()</h2><p>终止当前请求,xhr.send()后调用</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> url = <span class=\"string\">'https://www.imooc.com/api/http/search/suggest?words=js'</span>;</span><br><span class=\"line\"><span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest();</span><br><span class=\"line\">xhr.onreadystatechange = <span class=\"function\">() =></span> {}</span><br><span class=\"line\">xhr.open(<span class=\"string\">'GET'</span>, url, <span class=\"literal\">true</span>);</span><br><span class=\"line\">xhr.send(<span class=\"literal\">null</span>);</span><br><span class=\"line\">xhr.abort();</span><br></pre></td></tr></table></figure></div>\n\n<h2 id=\"7-2-xhr-setRequestHeader\"><a href=\"#7-2-xhr-setRequestHeader\" class=\"headerlink\" title=\"7.2.xhr.setRequestHeader()\"></a>7.2.xhr.setRequestHeader()</h2><p>设置请求头信息</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> url = <span class=\"string\">'https://www.imooc.com/api/http/search/suggest?words=js'</span>;</span><br><span class=\"line\"><span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest();</span><br><span class=\"line\">xhr.onreadystatechange = <span class=\"function\">() =></span> {}</span><br><span class=\"line\">xhr.open(<span class=\"string\">'POST'</span>, url, <span class=\"literal\">true</span>);</span><br><span class=\"line\"><span class=\"comment\">// Content-Type 告诉浏览器发送的数据格式</span></span><br><span class=\"line\"><span class=\"comment\">// 字符串</span></span><br><span class=\"line\">xhr.setRequestHeader(<span class=\"string\">'Content-Type'</span>,<span class=\"string\">'application/x-www-form-urlencoded'</span>);</span><br><span class=\"line\">xhr.send(<span class=\"string\">'username=CalDey&age=23'</span>);</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> url = <span class=\"string\">'https://www.imooc.com/api/http/json/search/suggest?words=js'</span>;</span><br><span class=\"line\"><span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest();</span><br><span class=\"line\">xhr.onreadystatechange = <span class=\"function\">() =></span> {}</span><br><span class=\"line\">xhr.open(<span class=\"string\">'POST'</span>, url, <span class=\"literal\">true</span>);</span><br><span class=\"line\"><span class=\"comment\">// Content-Type 告诉浏览器发送的数据格式</span></span><br><span class=\"line\"><span class=\"comment\">// JSON</span></span><br><span class=\"line\">xhr.setRequestHeader(<span class=\"string\">'Content-Type'</span>,<span class=\"string\">'application/json'</span>);</span><br><span class=\"line\">xhr.send(<span class=\"built_in\">JSON</span>.stringify({</span><br><span class=\"line\"> username: <span class=\"string\">'Caldey'</span>,</span><br><span class=\"line\"> age: <span class=\"number\">23</span></span><br><span class=\"line\">}))</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"8-xhr事件\"><a href=\"#8-xhr事件\" class=\"headerlink\" title=\"8.xhr事件\"></a>8.xhr事件</h1><h1 id=\"8-1-load事件\"><a href=\"#8-1-load事件\" class=\"headerlink\" title=\"8.1.load事件\"></a>8.1.load事件</h1><p>响应事件可用时触发,可替代readystatechange</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> url = <span class=\"string\">'https://www.imooc.com/api/http/search/suggest?words=js'</span>;</span><br><span class=\"line\"><span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest();</span><br><span class=\"line\">xhr.onload = <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">if</span>((xhr.status >= <span class=\"number\">200</span> && xhr.status < <span class=\"number\">300</span>) ||</span><br><span class=\"line\"> (xhr.status === <span class=\"number\">304</span>)) {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(xhr.response)</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\">xhr.open(<span class=\"string\">'GET'</span>, url, <span class=\"literal\">true</span>);</span><br><span class=\"line\">xhr.send(<span class=\"literal\">null</span>);</span><br></pre></td></tr></table></figure></div>\n\n<p>推荐和addEventListener搭配使用</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> url = <span class=\"string\">'https://www.imooc.com/api/http/search/suggest?words=js'</span>;</span><br><span class=\"line\"><span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest();</span><br><span class=\"line\">xhr.addEventListener(<span class=\"string\">'load'</span>, <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">if</span>((xhr.status >= <span class=\"number\">200</span> && xhr.status < <span class=\"number\">300</span>) ||</span><br><span class=\"line\"> (xhr.status === <span class=\"number\">304</span>)) {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(xhr.response)</span><br><span class=\"line\"> }</span><br><span class=\"line\">}, <span class=\"literal\">false</span>)</span><br><span class=\"line\">xhr.open(<span class=\"string\">'GET'</span>, url, <span class=\"literal\">true</span>);</span><br><span class=\"line\">xhr.send(<span class=\"literal\">null</span>);</span><br></pre></td></tr></table></figure></div>\n\n<h1 id=\"8-2-error事件\"><a href=\"#8-2-error事件\" class=\"headerlink\" title=\"8.2.error事件\"></a>8.2.error事件</h1><p><font color=#ff503e><strong>请求发送错误时触发</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> url = <span class=\"string\">'https://www.imooc123.com/api/http/search/suggest?words=js'</span>;</span><br><span class=\"line\"><span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest();</span><br><span class=\"line\">xhr.addEventListener(<span class=\"string\">'load'</span>, <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">if</span>((xhr.status >= <span class=\"number\">200</span> && xhr.status < <span class=\"number\">300</span>) ||</span><br><span class=\"line\"> (xhr.status === <span class=\"number\">304</span>)) {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(xhr.response)</span><br><span class=\"line\"> }</span><br><span class=\"line\">}, <span class=\"literal\">false</span>);</span><br><span class=\"line\">xhr.addEventListener(<span class=\"string\">'error'</span>, <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'error'</span>)</span><br><span class=\"line\">}, <span class=\"literal\">false</span>);</span><br><span class=\"line\">xhr.open(<span class=\"string\">'GET'</span>, url, <span class=\"literal\">true</span>);</span><br><span class=\"line\">xhr.send(<span class=\"literal\">null</span>);</span><br></pre></td></tr></table></figure></div>\n\n<h1 id=\"8-3-abort事件\"><a href=\"#8-3-abort事件\" class=\"headerlink\" title=\"8.3.abort事件\"></a>8.3.abort事件</h1><p>调用abort()时触发</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> url = <span class=\"string\">'https://www.imooc123.com/api/http/search/suggest?words=js'</span>;</span><br><span class=\"line\"><span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest();</span><br><span class=\"line\">xhr.addEventListener(<span class=\"string\">'load'</span>, <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">if</span>((xhr.status >= <span class=\"number\">200</span> && xhr.status < <span class=\"number\">300</span>) ||</span><br><span class=\"line\"> (xhr.status === <span class=\"number\">304</span>)) {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(xhr.response)</span><br><span class=\"line\"> }</span><br><span class=\"line\">}, <span class=\"literal\">false</span>);</span><br><span class=\"line\">xhr.addEventListener(<span class=\"string\">'abort'</span>, <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'abort'</span>)</span><br><span class=\"line\">}, <span class=\"literal\">false</span>);</span><br><span class=\"line\">xhr.open(<span class=\"string\">'GET'</span>, url, <span class=\"literal\">true</span>);</span><br><span class=\"line\">xhr.send(<span class=\"literal\">null</span>);</span><br><span class=\"line\">xhr.abort();</span><br></pre></td></tr></table></figure></div>\n\n<h1 id=\"8-4-timeout事件\"><a href=\"#8-4-timeout事件\" class=\"headerlink\" title=\"8.4.timeout事件\"></a>8.4.timeout事件</h1><p>请求超时触发</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> url = <span class=\"string\">'https://www.imooc123.com/api/http/search/suggest?words=js'</span>;</span><br><span class=\"line\"><span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest();</span><br><span class=\"line\">xhr.addEventListener(<span class=\"string\">'load'</span>, <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">if</span>((xhr.status >= <span class=\"number\">200</span> && xhr.status < <span class=\"number\">300</span>) ||</span><br><span class=\"line\"> (xhr.status === <span class=\"number\">304</span>)) {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(xhr.response)</span><br><span class=\"line\"> }</span><br><span class=\"line\">}, <span class=\"literal\">false</span>);</span><br><span class=\"line\">xhr.addEventListener(<span class=\"string\">'timeout'</span>, <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'timeout'</span>)</span><br><span class=\"line\">}, <span class=\"literal\">false</span>);</span><br><span class=\"line\">xhr.open(<span class=\"string\">'GET'</span>, url, <span class=\"literal\">true</span>);</span><br><span class=\"line\">xhr.timeout = <span class=\"number\">1</span>;</span><br><span class=\"line\">xhr.send(<span class=\"literal\">null</span>);</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-1分钟分清null和undefined","url":"/2020/12/16/JavaScript-1%E5%88%86%E9%92%9F%E5%88%86%E6%B8%85null%E5%92%8Cundefined/","content":"<p>JS中同时存在两个表示“无”的值:null和undefined,它们有什么区别?</p>\n<hr>\n<a id=\"more\"></a>\n\n<p>null表示”没有对象”,即该处不应该有值:</p>\n<ul>\n<li>作为函数的参数,表示该函数的参数不是对象</li>\n<li>作为原型链的终点</li>\n</ul>\n<p>undefined表示”缺少值”,就是此处应该有一个值,但是还没有定义:</p>\n<ul>\n<li>变量被声明了,但没有赋值时,就等于undefined</li>\n<li>调用函数时,应该提供的参数没有提供,该参数等于undefined</li>\n<li>对象没有赋值的属性,该属性的值为undefined</li>\n<li>函数没有返回值时,默认返回undefined</li>\n</ul>\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScipt-跨域","url":"/2021/02/21/JavaScipt-%E8%B7%A8%E5%9F%9F/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-什么是跨域?\"><a href=\"#1-什么是跨域?\" class=\"headerlink\" title=\"1.什么是跨域?\"></a>1.什么是跨域?</h1><p>ajax请求时,浏览器要求当前网页和server必须同源(保证安全,同源策略)<br>同源:协议,域名,端口三者必须一致<br>不同源的请求会被浏览器禁止</p>\n<p>https(协议)://<a href=\"http://www.baidu.com(域名)/\">www.baidu.com(域名)</a> :443(端口号)</p>\n<p>只有浏览器才会出现跨域问题</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> url = <span class=\"string\">'https://www.baidu.com'</span></span><br><span class=\"line\"><span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest()</span><br><span class=\"line\">xhr.open(<span class=\"string\">'GET'</span>, url, <span class=\"literal\">true</span>)</span><br><span class=\"line\">xhr.send(<span class=\"literal\">null</span>)</span><br><span class=\"line\"><span class=\"comment\">// Access to XMLHttpRequest at 'https://www.baidu.com/' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.</span></span><br></pre></td></tr></table></figure></div>\n\n<h1 id=\"2-解决跨域\"><a href=\"#2-解决跨域\" class=\"headerlink\" title=\"2.解决跨域\"></a>2.解决跨域</h1><h2 id=\"2-1-CORS跨域资源共享(后端)\"><a href=\"#2-1-CORS跨域资源共享(后端)\" class=\"headerlink\" title=\"2.1.CORS跨域资源共享(后端)\"></a>2.1.CORS跨域资源共享(后端)</h2><p>Access-Control-Allow-Origin:*<br>允许所有域名来跨域请求,*是通配符,没有任何限制</p>\n<p>Access-Control-Allow-Origin:<a href=\"http://127.0.0.1:5500/\">http://127.0.0.1:5500</a><br>只允许指定域名的跨域请求</p>\n<p>CORS跨域过程:</p>\n<p>①浏览器发送跨域请求<br>②后端在响应头中添加Access-Control-Allow-Origin<br>③浏览器接收到响应<br>④同域请求,前后端交互完成<br>⑤如果允许跨域,前后端交互完成<br>⑥不满足跨域条件,前后端交互失败</p>\n<p>CORS兼容性:IE10↑</p>\n<h2 id=\"2-2-JSONP\"><a href=\"#2-2-JSONP\" class=\"headerlink\" title=\"2.2.JSONP\"></a>2.2.JSONP</h2><p>JSONP实现原理: script标签</p>\n<p>使用JSONP实现跨域:</p>\n<p>①服务器端准备好JSONP接口<br>②手动加载JSONP或动态加载(script标签)<br>③声明函数</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><script></span><br><span class=\"line\"> <span class=\"comment\">// 手动加载</span></span><br><span class=\"line\"> <span class=\"comment\">// const handleResponse = data => {</span></span><br><span class=\"line\"> <span class=\"comment\">// console.log(data)</span></span><br><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\">const</span> script = <span class=\"built_in\">document</span>.createElement(<span class=\"string\">'script'</span>);</span><br><span class=\"line\"> script.src = <span class=\"string\">'https://www.imooc.com/api/http/jsonp?callback=handleResponse'</span></span><br><span class=\"line\"> <span class=\"built_in\">document</span>.body.appendChild(script);</span><br><span class=\"line\"></script></span><br><span class=\"line\"><script src=<span class=\"string\">"https://www.imooc.com/api/http/jsonp?callback=handleResponse"</span>></script></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-Ajax进阶","url":"/2021/02/22/JavaScript-Ajax%E8%BF%9B%E9%98%B6/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-FormData\"><a href=\"#1-FormData\" class=\"headerlink\" title=\"1.FormData\"></a>1.FormData</h1><p>表单提交默认会跳转,可以通过Ajax提交表单</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"HTML\"><figure class=\"iseeu highlight /html\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"tag\"><<span class=\"name\">form</span> <span class=\"attr\">id</span>=<span class=\"string\">"login"</span></span></span><br><span class=\"line\"><span class=\"tag\"><span class=\"attr\">action</span>=<span class=\"string\">"https://www.imooc.com/api/http/search/suggest?words=js"</span></span></span><br><span class=\"line\"><span class=\"tag\"><span class=\"attr\">method</span>=<span class=\"string\">"POST"</span></span></span><br><span class=\"line\"><span class=\"tag\"><span class=\"attr\">enctype</span>=<span class=\"string\">"application/x-www-form-urlencoded"</span>></span></span><br><span class=\"line\"> <span class=\"tag\"><<span class=\"name\">input</span> <span class=\"attr\">type</span>=<span class=\"string\">"text"</span> <span class=\"attr\">name</span>=<span class=\"string\">"username"</span> <span class=\"attr\">placeholder</span>=<span class=\"string\">"用户名"</span>></span></span><br><span class=\"line\"> <span class=\"tag\"><<span class=\"name\">input</span> <span class=\"attr\">type</span>=<span class=\"string\">"text"</span> <span class=\"attr\">name</span>=<span class=\"string\">"password"</span> <span class=\"attr\">placeholder</span>=<span class=\"string\">"密码"</span>></span></span><br><span class=\"line\"> <span class=\"tag\"><<span class=\"name\">input</span> <span class=\"attr\">id</span>=<span class=\"string\">"submit"</span> <span class=\"attr\">type</span>=<span class=\"string\">"submit"</span> <span class=\"attr\">type</span>=<span class=\"string\">"submit"</span> <span class=\"attr\">value</span>=<span class=\"string\">"登录"</span>></span></span><br><span class=\"line\"><span class=\"tag\"></<span class=\"name\">form</span>></span></span><br></pre></td></tr></table></figure></div>\n\n<p>使用Ajax提交表单:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 使用Ajax提交表单</span></span><br><span class=\"line\"><span class=\"keyword\">const</span> login = <span class=\"built_in\">document</span>.getElementById(<span class=\"string\">'login'</span>),</span><br><span class=\"line\"> { username, password } = login,</span><br><span class=\"line\"> btn = <span class=\"built_in\">document</span>.getElementById(<span class=\"string\">'submit'</span>),</span><br><span class=\"line\"> url = <span class=\"string\">'https://www.imooc.com/api/http/search/suggest?words=js'</span>;</span><br><span class=\"line\"></span><br><span class=\"line\">btn.addEventListener(<span class=\"string\">'click'</span>, <span class=\"function\"><span class=\"params\">e</span> =></span> {</span><br><span class=\"line\"> <span class=\"comment\">// 阻止默认行为</span></span><br><span class=\"line\"> e.preventDefault();</span><br><span class=\"line\"> <span class=\"comment\">// 发送Aajax请求</span></span><br><span class=\"line\"> <span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest();</span><br><span class=\"line\"> xhr.addEventListener(<span class=\"string\">'load'</span>, <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">if</span>((xhr.status >= <span class=\"number\">200</span> && xhr.status < <span class=\"number\">300</span>) ||</span><br><span class=\"line\"> (xhr.status === <span class=\"number\">304</span>))</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(xhr.response);</span><br><span class=\"line\"> }, <span class=\"literal\">false</span>);</span><br><span class=\"line\"> xhr.addEventListener(<span class=\"string\">'error'</span>, <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'error'</span>)</span><br><span class=\"line\"> }, <span class=\"literal\">false</span>);</span><br><span class=\"line\"> xhr.addEventListener(<span class=\"string\">'timeout'</span>, <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'timeout'</span>)</span><br><span class=\"line\"> }, <span class=\"literal\">false</span>);</span><br><span class=\"line\"> xhr.open(<span class=\"string\">'POST'</span>, url, <span class=\"literal\">true</span>);</span><br><span class=\"line\"> xhr.timeout = <span class=\"number\">10000</span>;</span><br><span class=\"line\"> <span class=\"comment\">// 组装数据</span></span><br><span class=\"line\"> <span class=\"comment\">// const data = `username=${username.value}&password=${password.value}`;</span></span><br><span class=\"line\"> <span class=\"comment\">// 通过FormData组装数据</span></span><br><span class=\"line\"> <span class=\"keyword\">const</span> data = <span class=\"keyword\">new</span> FormData(login);</span><br><span class=\"line\"> <span class=\"keyword\">for</span> (<span class=\"keyword\">const</span> i <span class=\"keyword\">of</span> data) {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(i);</span><br><span class=\"line\"> }</span><br><span class=\"line\"> xhr.setRequestHeader(<span class=\"string\">'Content-Type'</span>, <span class=\"string\">'application/x-www-form-urlencoded'</span>);</span><br><span class=\"line\"> xhr.send(data);</span><br><span class=\"line\">}, <span class=\"literal\">false</span>)</span><br></pre></td></tr></table></figure></div>\n\n<p>FormData可以通过append()添加数据:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> data = <span class=\"keyword\">new</span> FormData();</span><br><span class=\"line\">data.append(<span class=\"string\">'age'</span>, <span class=\"number\">23</span>);</span><br><span class=\"line\">data.append(<span class=\"string\">'gender'</span>, <span class=\"string\">'male'</span>);</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"2-封装简易Ajax\"><a href=\"#2-封装简易Ajax\" class=\"headerlink\" title=\"2.封装简易Ajax\"></a>2.封装简易Ajax</h1><h1 id=\"2-1-GET\"><a href=\"#2-1-GET\" class=\"headerlink\" title=\"2.1.GET\"></a>2.1.GET</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest()</span><br><span class=\"line\">xhr.open(<span class=\"string\">'GET'</span>, <span class=\"string\">'./data.json'</span>, <span class=\"literal\">true</span>)</span><br><span class=\"line\">xhr.onreadystatechange = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(xhr.readyState === <span class=\"number\">4</span>) {</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(xhr.status === <span class=\"number\">200</span>) {</span><br><span class=\"line\"> alert(xhr.responseText)</span><br><span class=\"line\"> }<span class=\"keyword\">else</span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'err'</span>)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\">xhr.send(<span class=\"literal\">null</span>)</span><br></pre></td></tr></table></figure></div>\n\n<h1 id=\"2-2-POST\"><a href=\"#2-2-POST\" class=\"headerlink\" title=\"2.2.POST\"></a>2.2.POST</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest()</span><br><span class=\"line\">xhr.open(<span class=\"string\">'POST'</span>, <span class=\"string\">'/login'</span>, <span class=\"literal\">true</span>)</span><br><span class=\"line\">xhr.onreadystatechange = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(xhr.readyState === <span class=\"number\">4</span>) {</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(xhr.status === <span class=\"number\">200</span>) {</span><br><span class=\"line\"> alert(xhr.responseText)</span><br><span class=\"line\"> }<span class=\"keyword\">else</span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'err'</span>)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">const</span> postData = {</span><br><span class=\"line\"> userName: <span class=\"string\">'CalDey'</span>,</span><br><span class=\"line\"> password: <span class=\"number\">123456</span></span><br><span class=\"line\">}</span><br><span class=\"line\">xhr.send(<span class=\"built_in\">JSON</span>.stringify(postData))</span><br></pre></td></tr></table></figure></div>\n\n<h1 id=\"2-3-增加Promise\"><a href=\"#2-3-增加Promise\" class=\"headerlink\" title=\"2.3.增加Promise\"></a>2.3.增加Promise</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">ajax</span>(<span class=\"params\">url</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">const</span> p = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest()</span><br><span class=\"line\"> xhr.open(<span class=\"string\">'GET'</span>, url, <span class=\"literal\">true</span>)</span><br><span class=\"line\"> xhr.onreadystatechange = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(xhr.readyState === <span class=\"number\">4</span>){</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(xhr.status === <span class=\"number\">200</span>){</span><br><span class=\"line\"> resolve(</span><br><span class=\"line\"> <span class=\"built_in\">JSON</span>.parse(xhr.responseText)</span><br><span class=\"line\"> )</span><br><span class=\"line\"> }<span class=\"keyword\">else</span> <span class=\"keyword\">if</span>(xhr.status === <span class=\"number\">404</span>) {</span><br><span class=\"line\"> reject(<span class=\"keyword\">new</span> <span class=\"built_in\">Error</span>(<span class=\"string\">'404 not found'</span>))</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\"> xhr.send(<span class=\"literal\">null</span>)</span><br><span class=\"line\"> })</span><br><span class=\"line\"> <span class=\"keyword\">return</span> p</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> url1 = <span class=\"string\">'./data.json'</span></span><br><span class=\"line\"><span class=\"keyword\">const</span> url2 = <span class=\"string\">'./data1.json'</span></span><br><span class=\"line\">ajax(url1).then(<span class=\"function\"><span class=\"params\">res</span> =></span> <span class=\"built_in\">console</span>.log(res)).catch(<span class=\"function\"><span class=\"params\">err</span> =></span> <span class=\"built_in\">console</span>.log(err))</span><br><span class=\"line\">ajax(url2).then(<span class=\"function\"><span class=\"params\">res</span> =></span> <span class=\"built_in\">console</span>.log(res)).catch(<span class=\"function\"><span class=\"params\">err</span> =></span> <span class=\"built_in\">console</span>.log(err))</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-BFC","url":"/2021/03/08/JavaScript-BFC/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-什么是BFC\"><a href=\"#1-什么是BFC\" class=\"headerlink\" title=\"1.什么是BFC\"></a>1.什么是BFC</h1><p>Block Formatting Context 块级格式化上下文</p>\n<p>形成一块独立的渲染区域,内部元素的渲染不会影响外界</p>\n<hr>\n<h1 id=\"2-触发BFC的常见条件\"><a href=\"#2-触发BFC的常见条件\" class=\"headerlink\" title=\"2.触发BFC的常见条件\"></a>2.触发BFC的常见条件</h1><p>①浮动:除了float:none<br>②position: absolute or fixed<br>③overflow: 除了visible<br>④flex<br>⑤inline-block</p>\n<h1 id=\"3-常见应用场景\"><a href=\"#3-常见应用场景\" class=\"headerlink\" title=\"3.常见应用场景\"></a>3.常见应用场景</h1><p>清除浮动</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/wkNKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-Promise,Promise.all,Promise.race","url":"/2021/03/31/JavaScript-Promise-Promise-all-Promise-race/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-Promise\"><a href=\"#1-Promise\" class=\"headerlink\" title=\"1.Promise\"></a>1.Promise</h1><p>Promise是异步操作,其可以解决异步的回调地狱问题,将回调函数的多层嵌套形式转化为单层管道结构(链式调用)</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> p1 = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\">resolve(<span class=\"string\">'123'</span>)</span><br><span class=\"line\">}).then(<span class=\"function\"><span class=\"params\">res</span> =></span> {</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(res)</span><br><span class=\"line\">})</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">let</span> p2 = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\">reject(<span class=\"string\">'456'</span>)</span><br><span class=\"line\">}).then(<span class=\"function\"><span class=\"params\">res</span> =></span> {</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"string\">'success'</span>)</span><br><span class=\"line\">}).catch(<span class=\"function\"><span class=\"params\">err</span> =></span> {</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(err)</span><br><span class=\"line\">})</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"string\">'123456'</span>)</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"2-Promise-all\"><a href=\"#2-Promise-all\" class=\"headerlink\" title=\"2.Promise.all\"></a>2.Promise.all</h1><p>Promise.all将多个promise实例合并成一个promise实例,若全部成功以数组的形式返回所有结果,失败则返回第一个reject的值</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> p1 = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\">resolve(<span class=\"string\">'成功'</span>)</span><br><span class=\"line\">})</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">let</span> p2 = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\">resolve(<span class=\"string\">'success'</span>)</span><br><span class=\"line\">})</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">let</span> p3 = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\">reject(<span class=\"string\">'error'</span>)</span><br><span class=\"line\">})</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">Promise</span>.all([p1,p2]).then(<span class=\"function\"><span class=\"params\">res</span> =></span> {</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(res) <span class=\"comment\">// ["成功","success"]</span></span><br><span class=\"line\">})</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">Promise</span>.all([p1,p2,p3]).then(<span class=\"function\"><span class=\"params\">res</span> =></span> {</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(res)</span><br><span class=\"line\">}).catch(<span class=\"function\"><span class=\"params\">err</span> =></span> {</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(err) <span class=\"comment\">// error</span></span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure></div>\n\n<p>Promise.all返回的数组中数据顺序和传入时的顺序是一致的,也就是说,即使第一个数据的获取晚于其他数据,其仍为数组第0项;在某些需要同时发送多次请求并且按顺序获取数据时,这种方法为开发带来了极大的便利</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> timer = <span class=\"function\">(<span class=\"params\">time</span>) =></span> {</span><br><span class=\"line\"><span class=\"keyword\">return</span> <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\"><span class=\"built_in\">setTimeout</span>(<span class=\"function\">() =></span> {</span><br><span class=\"line\">resolve(<span class=\"string\">`<span class=\"subst\">${time / <span class=\"number\">1000</span>}</span>秒后触发`</span>)</span><br><span class=\"line\">}, time)</span><br><span class=\"line\">})</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">let</span> p1 = timer(<span class=\"number\">3000</span>)</span><br><span class=\"line\"><span class=\"keyword\">let</span> p2 = timer(<span class=\"number\">1000</span>)</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">Promise</span>.all([p1, p2]).then(<span class=\"function\"><span class=\"params\">res</span> =></span> {</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(res) <span class=\"comment\">// ["3秒后触发","1秒后触发"]</span></span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"3-Promise-race\"><a href=\"#3-Promise-race\" class=\"headerlink\" title=\"3.Promise.race\"></a>3.Promise.race</h1><p>基本用法与Promise相似,其返回结果取决于哪个实例最先返回结果,无论结果是成功或失败</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> p1 = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\"><span class=\"built_in\">setTimeout</span>(<span class=\"function\">() =></span> {</span><br><span class=\"line\">resolve(<span class=\"string\">'success'</span>)</span><br><span class=\"line\">}, <span class=\"number\">1000</span>)</span><br><span class=\"line\">})</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">let</span> p2 = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\"><span class=\"built_in\">setTimeout</span>(<span class=\"function\">() =></span> {</span><br><span class=\"line\">reject(<span class=\"string\">'error'</span>)</span><br><span class=\"line\">}, <span class=\"number\">500</span>)</span><br><span class=\"line\">})</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">Promise</span>.all([p1, p2]).then(<span class=\"function\"><span class=\"params\">res</span> =></span> {</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(res) <span class=\"comment\">// ["3秒后触发","1秒后触发"]</span></span><br><span class=\"line\">}).catch(<span class=\"function\"><span class=\"params\">err</span> =></span> {</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(err) <span class=\"comment\">// error</span></span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-Promise","url":"/2021/02/20/JavaScript-Promise/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-callback-hell(回调地狱)\"><a href=\"#1-callback-hell(回调地狱)\" class=\"headerlink\" title=\"1.callback hell(回调地狱)\"></a>1.callback hell(回调地狱)</h1><p>在实际开发中,我们可以通过ajax使用回调函数获取后端接口返回的数据。但一旦开发一些复杂功能的应用时,一个页面可能需要调用多个接口数据,这时便形成了回调地狱:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 获取第一份数据</span></span><br><span class=\"line\"> $.get(url1, <span class=\"function\">(<span class=\"params\">data</span>) =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(data1)</span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"comment\">// 获取第二份数据</span></span><br><span class=\"line\"> $.get(url2, <span class=\"function\">(<span class=\"params\">data2</span>) =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(data2)</span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"comment\">// 获取第三份数据</span></span><br><span class=\"line\"> $.get(url3, <span class=\"function\">(<span class=\"params\">data3</span>) =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(data3)</span><br><span class=\"line\"></span><br><span class=\"line\"> <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></div>\n\n<p>回调函数层层嵌套,形成了回调地狱,这样的代码既难以阅读,又不方便维护</p>\n<hr>\n<h1 id=\"2-Promise\"><a href=\"#2-Promise\" class=\"headerlink\" title=\"2.Promise\"></a>2.Promise</h1><p>Promise是异步操作的一种解决方案,一般用来解决层层嵌套的回调函数</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">getData</span>(<span class=\"params\">url</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\"> $.ajax({</span><br><span class=\"line\"> <span class=\"function\"><span class=\"title\">success</span>(<span class=\"params\">data</span>)</span>{</span><br><span class=\"line\"> resolve(data)</span><br><span class=\"line\"> },</span><br><span class=\"line\"> <span class=\"function\"><span class=\"title\">error</span>(<span class=\"params\">err</span>)</span>{</span><br><span class=\"line\"> reject(err)</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><span class=\"line\"><span class=\"keyword\">const</span> url1 = <span class=\"string\">'/data1.json'</span></span><br><span class=\"line\"><span class=\"keyword\">const</span> url2 = <span class=\"string\">'/data2.json'</span></span><br><span class=\"line\"><span class=\"keyword\">const</span> url3 = <span class=\"string\">'/data3.json'</span></span><br><span class=\"line\">getData(url1).then(<span class=\"function\"><span class=\"params\">data1</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(data1)</span><br><span class=\"line\"> <span class=\"keyword\">return</span> getData(url2)</span><br><span class=\"line\">}).then(<span class=\"function\"><span class=\"params\">data2</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(data2)</span><br><span class=\"line\"> <span class=\"keyword\">return</span> getData(url3)</span><br><span class=\"line\">}).then(<span class=\"function\"><span class=\"params\">data3</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(data3)</span><br><span class=\"line\">}).catch(<span class=\"function\"><span class=\"params\">err</span> =></span> <span class=\"built_in\">console</span>.log(err))</span><br></pre></td></tr></table></figure></div>\n\n<p>Promise最大的特点就是将callback回调函数由最初的层层嵌套转化为单层管道式结构(链式调用)</p>\n<hr>\n<h1 id=\"3-Promise基本用法\"><a href=\"#3-Promise基本用法\" class=\"headerlink\" title=\"3.Promise基本用法\"></a>3.Promise基本用法</h1><p>Promise解决的是回调地狱,仍然使用回调函数</p>\n<p>Promise的三种状态:</p>\n<ul>\n<li>pending(未完成)</li>\n<li>fulfilled(resolved)(已成功)</li>\n<li></li>\n</ul>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> p = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {});</span><br><span class=\"line\"><span class=\"comment\">// 初始态</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(p) <span class=\"comment\">// Promise {<pending>}</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> p = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\"> resolve();</span><br><span class=\"line\">});</span><br><span class=\"line\"><span class=\"comment\">// pending -> fulfilled</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(p)</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> p = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\"> reject();</span><br><span class=\"line\">});</span><br><span class=\"line\"><span class=\"comment\">// pending -> rejected</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(p)</span><br></pre></td></tr></table></figure></div>\n\n<p>Promise的状态一旦发生变化,就不会再改变了</p>\n<h1 id=\"4-then和catch\"><a href=\"#4-then和catch\" class=\"headerlink\" title=\"4.then和catch\"></a>4.then和catch</h1><p><font color=#ff503e><strong>注意:Promise构造函数本身是同步,但Promise的回调函数then是异步的</strong></font></p>\n<p>捕获异常是程序质量保障最基本的要求,可以使用catch来捕获异步操作过程中出现的任何异常</p>\n<p>pendding状态不会触发then和catch<br>fulfilled状态会触发后续的then回调函数<br>rejected会触发后续的catch回调函数</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> p = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>.resolve(<span class=\"number\">100</span>)</span><br><span class=\"line\">p.then(<span class=\"function\"><span class=\"params\">data</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'data'</span>, data) <span class=\"comment\">// data 100</span></span><br><span class=\"line\">}).catch(<span class=\"function\"><span class=\"params\">err</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'err'</span>, err)</span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> p = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>.reject(<span class=\"string\">'err'</span>)</span><br><span class=\"line\">p.then(<span class=\"function\"><span class=\"params\">data</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'data'</span>, data)</span><br><span class=\"line\">}).catch(<span class=\"function\"><span class=\"params\">err</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'err'</span>, err) <span class=\"comment\">// err err</span></span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure></div>\n\n<h1 id=\"5-then和catch改变状态\"><a href=\"#5-then和catch改变状态\" class=\"headerlink\" title=\"5.then和catch改变状态\"></a>5.then和catch改变状态</h1><p>then正常返回fulfilled,里面有报错则返回rejected</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> p1 = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>.resolve().then(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"number\">100</span></span><br><span class=\"line\">})</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"string\">'p1'</span>, p1) <span class=\"comment\">// fulfilled</span></span><br><span class=\"line\">p1.then(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'123'</span>) <span class=\"comment\">// 123</span></span><br><span class=\"line\">})</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> p2 = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>.resolve().then(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> <span class=\"built_in\">Error</span>(<span class=\"string\">'then error'</span>)</span><br><span class=\"line\">})</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"string\">'p2'</span>, p2) <span class=\"comment\">// fulfilled</span></span><br><span class=\"line\">p2.then(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'456'</span>) <span class=\"comment\">// 不执行</span></span><br><span class=\"line\">}).catch(<span class=\"function\"><span class=\"params\">err</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.error(<span class=\"string\">'error'</span>, <span class=\"number\">100</span>) <span class=\"comment\">// 执行</span></span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure></div>\n\n<p>catch正常返回resolved,里面有报错则返回rejected</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> p1 = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>.reject(<span class=\"string\">'my error'</span>).catch(<span class=\"function\"><span class=\"params\">err</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.error(err)</span><br><span class=\"line\">})</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"string\">'p1'</span>, p1) <span class=\"comment\">// fulfilled 触发then回调</span></span><br><span class=\"line\">p1.then(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'123'</span>) <span class=\"comment\">// 123</span></span><br><span class=\"line\">})</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> p2 = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>.reject(<span class=\"string\">'my error'</span>).catch(<span class=\"function\"><span class=\"params\">err</span> =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> <span class=\"built_in\">Error</span>(<span class=\"string\">'catch err'</span>)</span><br><span class=\"line\">})</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"string\">'p2'</span>, p2) <span class=\"comment\">// rejected 触发catch回调</span></span><br><span class=\"line\">p2.then(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'456'</span>)</span><br><span class=\"line\">}).catch(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'this is err'</span>) <span class=\"comment\">// this is error</span></span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure></div>\n\n<h1 id=\"6-finally\"><a href=\"#6-finally\" class=\"headerlink\" title=\"6.finally\"></a>6.finally</h1><p>指定不管最后状态如何都会执行的回调函数</p>\n<p>在promise执行结束时,无论结果是fulfilled或者是rejected,在执行then()和catch()后,都会执行finally指定的回调函数。这为指定执行完promise后,无论结果是fulfilled还是rejected都需要执行的代码提供了一种方式,避免同样的语句需要在then()和catch()中各写一次的情况</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">setTimeout</span>(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> resolve(<span class=\"string\">'success'</span>)</span><br><span class=\"line\"> <span class=\"comment\">// reject('fail')</span></span><br><span class=\"line\"> }, <span class=\"number\">1000</span>)</span><br><span class=\"line\">}).then(<span class=\"function\"><span class=\"params\">res</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(res)</span><br><span class=\"line\">}).catch(<span class=\"function\"><span class=\"params\">err</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(err)</span><br><span class=\"line\">}).finally(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'finally'</span>)</span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"7-面试题\"><a href=\"#7-面试题\" class=\"headerlink\" title=\"7.面试题\"></a>7.面试题</h1><p>第一题</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">Promise</span>.resolve().then(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">1</span>) <span class=\"comment\">// 执行</span></span><br><span class=\"line\">}).catch(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">2</span>)</span><br><span class=\"line\">}).then(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">3</span>) <span class=\"comment\">// 执行</span></span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure></div>\n\n<p>第二题</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">Promise</span>.resolve().then(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">1</span>) <span class=\"comment\">// 执行</span></span><br><span class=\"line\"> <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> <span class=\"built_in\">Error</span>(<span class=\"string\">'err1'</span>)</span><br><span class=\"line\">}).catch(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">2</span>) <span class=\"comment\">// 执行</span></span><br><span class=\"line\">}).then(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">3</span>) <span class=\"comment\">// 执行</span></span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure></div>\n\n<p>第三题</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">Promise</span>.resolve().then(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">1</span>) <span class=\"comment\">// 执行</span></span><br><span class=\"line\"> <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> <span class=\"built_in\">Error</span>(<span class=\"string\">'err1'</span>)</span><br><span class=\"line\">}).catch(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">2</span>) <span class=\"comment\">// 执行</span></span><br><span class=\"line\">}).catch(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">3</span>) <span class=\"comment\">// 不执行</span></span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure></div>\n\n<p>第四题</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> p = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\"> reject(<span class=\"number\">1</span>)</span><br><span class=\"line\">})</span><br><span class=\"line\">p.then(</span><br><span class=\"line\"> (data) => {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(data)</span><br><span class=\"line\"> },</span><br><span class=\"line\"> (data) => {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(data) <span class=\"comment\">// 1</span></span><br><span class=\"line\"> }</span><br><span class=\"line\">).then(</span><br><span class=\"line\"> () => {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'a'</span>) <span class=\"comment\">// a</span></span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"number\">2</span></span><br><span class=\"line\"> },</span><br><span class=\"line\"> () => {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'b'</span>)</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"number\">3</span></span><br><span class=\"line\"> }</span><br><span class=\"line\">).then(</span><br><span class=\"line\"> (data) => {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(data) <span class=\"comment\">// 2</span></span><br><span class=\"line\"> },</span><br><span class=\"line\"> (data) => {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(data)</span><br><span class=\"line\"> }</span><br><span class=\"line\">) </span><br></pre></td></tr></table></figure></div>\n\n<p>第五题</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> p = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">1</span>) <span class=\"comment\">// 1</span></span><br><span class=\"line\"> resolve(<span class=\"number\">2</span>)</span><br><span class=\"line\">})</span><br><span class=\"line\">p.then(<span class=\"function\">(<span class=\"params\">res</span>) =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(res) <span class=\"comment\">// 2</span></span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"number\">3</span></span><br><span class=\"line\">})</span><br><span class=\"line\">.catch(<span class=\"function\">(<span class=\"params\">err</span>) =></span> <span class=\"number\">4</span>)</span><br><span class=\"line\">.then(<span class=\"function\"><span class=\"params\">res</span> =></span> <span class=\"built_in\">console</span>.log(res)) <span class=\"comment\">// 3</span></span><br></pre></td></tr></table></figure></div>\n\n<p>第六题</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> p = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\"> reject();</span><br><span class=\"line\"> resolve();</span><br><span class=\"line\">})</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(p) <span class=\"comment\">// rejected</span></span><br></pre></td></tr></table></figure></div>\n\n<p>promise状态变化: pendding -> resolve or pendding -> rejected</p>\n<p>该过程不可逆,状态一旦改变不能更改</p>\n<p>第七题</p>\n<p>通过Prmoise实现异步加载图片</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">loadImg</span>(<span class=\"params\">src</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(</span><br><span class=\"line\"> (resolve, reject) => {</span><br><span class=\"line\"> <span class=\"keyword\">const</span> img = <span class=\"built_in\">document</span>.createElement(<span class=\"string\">'img'</span>)</span><br><span class=\"line\"> img.onload = <span class=\"function\">() =></span> {</span><br><span class=\"line\"> resolve(img)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> img.onerror = <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">const</span> err = <span class=\"keyword\">new</span> <span class=\"built_in\">Error</span>(<span class=\"string\">`图片加载失败 <span class=\"subst\">${src}</span>`</span>)</span><br><span class=\"line\"> reject(err)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> img.src = src</span><br><span class=\"line\"> }</span><br><span class=\"line\"> )</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> url1 = <span class=\"string\">'https://gitee.com/caldey/BlogImage/raw/master/img/avatar.jpg'</span></span><br><span class=\"line\"><span class=\"keyword\">const</span> url2 = <span class=\"string\">'https://gitee.com/caldey/BlogImage/raw/master/img/img.jpg'</span></span><br><span class=\"line\"></span><br><span class=\"line\">loadImg(url1).then(<span class=\"function\"><span class=\"params\">img1</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(img1.width)</span><br><span class=\"line\"> <span class=\"keyword\">return</span> img1</span><br><span class=\"line\">}).then(<span class=\"function\"><span class=\"params\">img1</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(img1.height)</span><br><span class=\"line\"> <span class=\"keyword\">return</span> loadImg(url2)</span><br><span class=\"line\">}).then(<span class=\"function\"><span class=\"params\">img2</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(img2.width)</span><br><span class=\"line\"> <span class=\"keyword\">return</span> img2</span><br><span class=\"line\">}).then(<span class=\"function\"><span class=\"params\">img2</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(img2.height)</span><br><span class=\"line\">}).catch(<span class=\"function\"><span class=\"params\">ex</span> =></span> <span class=\"built_in\">console</span>.error(ex))</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<blockquote>\n<p>内容参考自:<a href=\"http://es.xiecheng.live/es6/promise.html\">ECMAScript2015~2020语法全解析</a></p>\n</blockquote>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-async/await","url":"/2021/02/21/JavaScript-async-await/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-什么是async-await?\"><a href=\"#1-什么是async-await?\" class=\"headerlink\" title=\"1.什么是async/await?\"></a>1.什么是async/await?</h1><p>async/await是一种更加优雅的异步编程解决方案,是Promise的拓展</p>\n<p>使用Promise可以非常简单的书写异步代码,但处理多个彼此之间相互依赖的请求时,就显得有些繁琐</p>\n<p>现在,我们可以通过async/await通过同步代码执行异步操作</p>\n<hr>\n<h1 id=\"2-async-await和Promise的关系\"><a href=\"#2-async-await和Promise的关系\" class=\"headerlink\" title=\"2.async/await和Promise的关系\"></a>2.async/await和Promise的关系</h1><p>async/await是解决异步回调的终极方案,但并不会与Promise冲突,二者相辅相成</p>\n<hr>\n<h1 id=\"3-基本用法\"><a href=\"#3-基本用法\" class=\"headerlink\" title=\"3.基本用法\"></a>3.基本用法</h1><p>添加了async的函数在执行后会自动返回一个Promise对象</p>\n <div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">async</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">fn</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"comment\">// reutrn 100 相当于 return Promise.resolve(100) 封装成一个Promise对象</span></span><br><span class=\"line\"> <span class=\"comment\">// return Promise.resolve(100)</span></span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"number\">100</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>async单独使用没有意义,其后面必须跟异步操作,await可以看做是Promise的then</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">async</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">fn</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"number\">100</span></span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> res = fn()</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(res) <span class=\"comment\">// Promise {<fulfilled>: 100}</span></span><br><span class=\"line\">res.then(<span class=\"function\"><span class=\"params\">data</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'data'</span>, data) <span class=\"comment\">// data 100</span></span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">;(<span class=\"keyword\">async</span> <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">const</span> p = <span class=\"built_in\">Promise</span>.resolve(<span class=\"number\">100</span>)</span><br><span class=\"line\"> <span class=\"keyword\">const</span> data = <span class=\"keyword\">await</span> p <span class=\"comment\">// await 相当于Promise then</span></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'data'</span>, data)</span><br><span class=\"line\">})()</span><br></pre></td></tr></table></figure></div>\n\n<p>不难看出其实async/await是通过同步语法书写Promise代码</p>\n<p>async/await和Promise一样,也可以捕获异常</p>\n<p>try…catch可以捕获异常,代替了Promise的catch</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">;(<span class=\"keyword\">async</span> <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>)</span>{</span><br><span class=\"line\"> <span class=\"keyword\">const</span> p = <span class=\"built_in\">Promise</span>.reject(<span class=\"string\">'err'</span>) <span class=\"comment\">// rejected</span></span><br><span class=\"line\"> <span class=\"keyword\">const</span> res = <span class=\"keyword\">await</span> p <span class=\"comment\">// await ->then</span></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(res) <span class=\"comment\">// 不执行</span></span><br><span class=\"line\">})() <span class=\"comment\">// Uncaught (in promise) err</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">;(<span class=\"keyword\">async</span> <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>)</span>{</span><br><span class=\"line\"> <span class=\"keyword\">const</span> p = <span class=\"built_in\">Promise</span>.reject(<span class=\"string\">'err'</span>) <span class=\"comment\">// rejected</span></span><br><span class=\"line\"> <span class=\"keyword\">try</span>{</span><br><span class=\"line\"> <span class=\"keyword\">const</span> res = <span class=\"keyword\">await</span> p <span class=\"comment\">// await ->then</span></span><br><span class=\"line\"> }<span class=\"keyword\">catch</span>(res){</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(res) <span class=\"comment\">// err</span></span><br><span class=\"line\"> }</span><br><span class=\"line\">})()</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"4-async-await的本质\"><a href=\"#4-async-await的本质\" class=\"headerlink\" title=\"4.async/await的本质\"></a>4.async/await的本质</h1><p>async/await是语法糖,其本质仍是异步,await后面的代码可以看做是callback</p>\n<p>先执行同步,后执行异步</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">timeout</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\"><span class=\"params\">resolve</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">setTimeout</span>(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">1</span>) <span class=\"comment\">// 注意这里是同步</span></span><br><span class=\"line\"> resolve() <span class=\"comment\">// resolve('success')</span></span><br><span class=\"line\"> }, <span class=\"number\">1000</span>)</span><br><span class=\"line\"> })</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"comment\">// 不加async和await是2、1 加了是1、2</span></span><br><span class=\"line\"><span class=\"keyword\">async</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">foo</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">await</span> timeout() <span class=\"comment\">// let res = await timeout() res是success</span></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">2</span>)</span><br><span class=\"line\">}</span><br><span class=\"line\">foo()</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">async</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">async1</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'async1 start'</span>) <span class=\"comment\">// 2</span></span><br><span class=\"line\"> <span class=\"keyword\">await</span> async2()</span><br><span class=\"line\"> <span class=\"comment\">// await 后面的内容都可以看做是callback 即异步</span></span><br><span class=\"line\"> <span class=\"comment\">// 类似于event loop 执行 setTimeout(function(){})</span></span><br><span class=\"line\"> <span class=\"comment\">// 或 promise.resolve().then(()=>{})</span></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'async1 end'</span>) <span class=\"comment\">// 5</span></span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">async</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">async2</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'async2'</span>) <span class=\"comment\">// 3</span></span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"string\">'script start'</span>) <span class=\"comment\">// 1</span></span><br><span class=\"line\">async1()</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"string\">'script end'</span>) <span class=\"comment\">// 4</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">async</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">async1</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'async1 start'</span>) <span class=\"comment\">// 2</span></span><br><span class=\"line\"> <span class=\"keyword\">await</span> async2()</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'async1 end'</span>) <span class=\"comment\">// 5</span></span><br><span class=\"line\"> <span class=\"keyword\">await</span> async3()</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'async1 end 2'</span>) <span class=\"comment\">// 7</span></span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">async</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">async2</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'async2'</span>) <span class=\"comment\">// 3</span></span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">async</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">async3</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'async3'</span>) <span class=\"comment\">// 6</span></span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"string\">'script start'</span>) <span class=\"comment\">// 1</span></span><br><span class=\"line\">async1()</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"string\">'script end'</span>) <span class=\"comment\">// 4</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"5-面试题\"><a href=\"#5-面试题\" class=\"headerlink\" title=\"5.面试题\"></a>5.面试题</h1><p>第一题</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">async</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">fn</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"number\">100</span></span><br><span class=\"line\">}</span><br><span class=\"line\">;(<span class=\"keyword\">async</span> <span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">const</span> a = fn() <span class=\"comment\">// Promise对象</span></span><br><span class=\"line\"> <span class=\"keyword\">const</span> b = <span class=\"keyword\">await</span> fn() <span class=\"comment\">// awit -> then</span></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a) <span class=\"comment\">// Promise {<fulfilled>: 100}</span></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(b) <span class=\"comment\">// 100</span></span><br><span class=\"line\">})()</span><br></pre></td></tr></table></figure></div>\n\n<p>第二题</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">;(<span class=\"keyword\">async</span> <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'start'</span>) <span class=\"comment\">// 1.1</span></span><br><span class=\"line\"> <span class=\"keyword\">const</span> a = <span class=\"keyword\">await</span> <span class=\"number\">100</span></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'a'</span>, a) <span class=\"comment\">// 2.a 100</span></span><br><span class=\"line\"> <span class=\"keyword\">const</span> b = <span class=\"keyword\">await</span> <span class=\"built_in\">Promise</span>.resolve(<span class=\"number\">200</span>)</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'b'</span>, b) <span class=\"comment\">// 3.b 200</span></span><br><span class=\"line\"> <span class=\"keyword\">const</span> c = <span class=\"keyword\">await</span> <span class=\"built_in\">Promise</span>.reject(<span class=\"number\">300</span>)</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'c'</span>, c) <span class=\"comment\">// 报错</span></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'end'</span>) <span class=\"comment\">// 不打印</span></span><br><span class=\"line\">})()</span><br></pre></td></tr></table></figure></div>\n\n<p>第三题</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">loadImg</span>(<span class=\"params\">src</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(</span><br><span class=\"line\"> (resolve, reject) => {</span><br><span class=\"line\"> <span class=\"keyword\">const</span> img = <span class=\"built_in\">document</span>.createElement(<span class=\"string\">'img'</span>)</span><br><span class=\"line\"> img.onload = <span class=\"function\">() =></span> {</span><br><span class=\"line\"> resolve(img)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> img.onerror = <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">const</span> err = <span class=\"keyword\">new</span> <span class=\"built_in\">Error</span>(<span class=\"string\">`图片加载失败 <span class=\"subst\">${src}</span>`</span>)</span><br><span class=\"line\"> reject(img)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> img.src = src</span><br><span class=\"line\"> }</span><br><span class=\"line\"> )</span><br><span class=\"line\"> }</span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"keyword\">const</span> url1 = <span class=\"string\">'https://gitee.com/caldey/BlogImage/raw/master/img/avatar.jpg'</span></span><br><span class=\"line\"> <span class=\"keyword\">const</span> url2 = <span class=\"string\">'https://gitee.com/caldey/BlogImage/raw/master/img/img.jpg'</span></span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"keyword\">async</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">loadImg1</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">const</span> img1 = <span class=\"keyword\">await</span> loadImg(url1)</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(img1.height)</span><br><span class=\"line\"> }</span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"keyword\">async</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">loadImg2</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">const</span> img2 = <span class=\"keyword\">await</span> loadImg(url2)</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(img2.height)</span><br><span class=\"line\"> }</span><br><span class=\"line\"></span><br><span class=\"line\"> loadImg1()</span><br><span class=\"line\"> loadImg2()</span><br></pre></td></tr></table></figure></div>\n\n<p>①同步代码执行完毕(event loop -> call stack被清空)<br>②执行微任务<br>③尝试触发DOM渲染<br>④触发Event loop,执行宏任务</p>\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-axios","url":"/2021/02/22/JavaScript-axios/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-axios\"><a href=\"#1-axios\" class=\"headerlink\" title=\"1.axios\"></a>1.axios</h1><p>axios是一个基于Promise的HTTP库,第三方Ajax库</p>\n<p><a href=\"http://www.axios-js.com/zh-cn/docs\">axios中文文档</a></p>\n<h1 id=\"1-1-GET\"><a href=\"#1-1-GET\" class=\"headerlink\" title=\"1.1.GET\"></a>1.1.GET</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><script src=<span class=\"string\">"https://unpkg.com/axios@0.19.2/dist/axios.min.js"</span>></script></span><br><span class=\"line\"><script></span><br><span class=\"line\"><span class=\"keyword\">const</span> url = <span class=\"string\">'https://www.imooc.com/api/http/search/suggest?words=js'</span>;</span><br><span class=\"line\">axios.get(url, {</span><br><span class=\"line\"> params: {</span><br><span class=\"line\"> username: <span class=\"string\">'alex'</span></span><br><span class=\"line\"> }</span><br><span class=\"line\">})</span><br><span class=\"line\">.then(<span class=\"function\"><span class=\"params\">response</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(response);</span><br><span class=\"line\">});</span><br><span class=\"line\"></script></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"1-2-POST\"><a href=\"#1-2-POST\" class=\"headerlink\" title=\"1.2.POST\"></a>1.2.POST</h2><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><script src=<span class=\"string\">"https://unpkg.com/axios@0.19.2/dist/axios.min.js"</span>></script></span><br><span class=\"line\"><script></span><br><span class=\"line\"><span class=\"keyword\">const</span> url = <span class=\"string\">'https://www.imooc.com/api/http/search/suggest?words=js'</span>;</span><br><span class=\"line\">axios.post(url, <span class=\"string\">'username=alex&age=18'</span>)</span><br><span class=\"line\">.then(<span class=\"function\"><span class=\"params\">response</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(response);</span><br><span class=\"line\">})</span><br><span class=\"line\">.catch(<span class=\"function\"><span class=\"params\">err</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(err);</span><br><span class=\"line\">});</span><br><span class=\"line\"></script></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScipt-event loop","url":"/2021/02/21/JavaScript-event%20loop/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-event-loop\"><a href=\"#1-event-loop\" class=\"headerlink\" title=\"1.event loop\"></a>1.event loop</h1><p>在JS中,同步和异步的执行顺序基于event loop:</p>\n<p>①同步代码一行行在Call Steak中执行<br>②遇到异步代码,先存放在Web APIs中等待时机(定时,网络请求…)<br>③时机一到,异步移动到Callback Queue队列中等待<br>④如果Call Steak为空,Event loop开始工作<br>⑤轮询查找Callback Queue,如果找到移动到Call Steak中执行<br>⑥不断重复执行上一步(永动机)</p>\n<p>注意:DOM事件和异步一样使用回调,基于event loop,但DOM事件不是异步</p>\n<hr>\n<h1 id=\"2-event-loop和DOM渲染\"><a href=\"#2-event-loop和DOM渲染\" class=\"headerlink\" title=\"2.event loop和DOM渲染\"></a>2.event loop和DOM渲染</h1><p>JS是单线程,和DOM渲染共用同一个线程</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><body></span><br><span class=\"line\"> <div id=<span class=\"string\">"container"</span>></div></span><br><span class=\"line\"></body></span><br><span class=\"line\"><script src=<span class=\"string\">"https://cdn.jsdelivr.net/gh/jquery/jquery@3.2.1/dist/jquery.min.js"</span>></script></span><br><span class=\"line\"><script></span><br><span class=\"line\"> <span class=\"keyword\">const</span> $p1 = $(<span class=\"string\">'<p>这是一段文字</p>'</span>)</span><br><span class=\"line\"> <span class=\"keyword\">const</span> $p2 = $(<span class=\"string\">'<p>这是一段文字</p>'</span>)</span><br><span class=\"line\"> <span class=\"keyword\">const</span> $p3 = $(<span class=\"string\">'<p>这是一段文字</p>'</span>)</span><br><span class=\"line\"> $(<span class=\"string\">'#container'</span>)</span><br><span class=\"line\"> .append($p1)</span><br><span class=\"line\"> .append($p2)</span><br><span class=\"line\"> .append($p3)</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'length'</span>, $(<span class=\"string\">'#container'</span>).children().length) <span class=\"comment\">// 3</span></span><br><span class=\"line\"> alert(<span class=\"string\">'本次轮询结束,DOM已更新,但未触发渲染'</span>)</span><br></pre></td></tr></table></figure></div>\n\n<p>alert阻塞了DOM渲染,alert事件不结束,永远无法进行DOM渲染</p>\n<hr>\n<h1 id=\"3-微任务和宏任务\"><a href=\"#3-微任务和宏任务\" class=\"headerlink\" title=\"3.微任务和宏任务\"></a>3.微任务和宏任务</h1><p>微任务:Promise async/await<br>宏任务:setTimeout,setInterval,Ajax,DOM事件</p>\n<p>在Call Steak空闲时(一次轮询结束),尝试DOM渲染,然后再次触发</p>\n<p>微任务:DOM渲染前触发,如Promise<br>宏任务:DOM渲染后触发,setTimeout</p>\n<p><font color=#ff503e><strong>微任务执行时机比宏任务早</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><body></span><br><span class=\"line\"> <div id=<span class=\"string\">"container"</span>></div></span><br><span class=\"line\"></body></span><br><span class=\"line\"><script src=<span class=\"string\">"https://cdn.jsdelivr.net/gh/jquery/jquery@3.2.1/dist/jquery.min.js"</span>></script></span><br><span class=\"line\"><script></span><br><span class=\"line\"> <span class=\"keyword\">const</span> $p1 = $(<span class=\"string\">'<p>这是一段文字</p>'</span>)</span><br><span class=\"line\"> <span class=\"keyword\">const</span> $p2 = $(<span class=\"string\">'<p>这是一段文字</p>'</span>)</span><br><span class=\"line\"> <span class=\"keyword\">const</span> $p3 = $(<span class=\"string\">'<p>这是一段文字</p>'</span>)</span><br><span class=\"line\"> $(<span class=\"string\">'#container'</span>)</span><br><span class=\"line\"> .append($p1)</span><br><span class=\"line\"> .append($p2)</span><br><span class=\"line\"> .append($p3)</span><br><span class=\"line\"> </span><br><span class=\"line\"> <span class=\"comment\">// 微任务 DOM渲染前触发</span></span><br><span class=\"line\"> <span class=\"built_in\">Promise</span>.resolve().then(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'length'</span>, $(<span class=\"string\">'#container'</span>).children().length)</span><br><span class=\"line\"> alert(<span class=\"string\">'Promise执行,DOM未渲染'</span>)</span><br><span class=\"line\"> })</span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"comment\">// 宏任务 DOM渲染后触发</span></span><br><span class=\"line\"> <span class=\"built_in\">setTimeout</span>(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'length'</span>, $(<span class=\"string\">'#container'</span>).children().length)</span><br><span class=\"line\"> alert(<span class=\"string\">'setTimeout执行,DOM已渲染'</span>)</span><br><span class=\"line\"> })</span><br><span class=\"line\"></script></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"4-event-loop过程图示\"><a href=\"#4-event-loop过程图示\" class=\"headerlink\" title=\"4.event loop过程图示\"></a>4.event loop过程图示</h1><p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/event%20loop.png\"></p>\n<p><font color=#ff503e><strong>执行顺序:同步 -> 微任务 -> DOM渲染 -> 宏任务</strong></font></p>\n<p>从event loop角度解释,为什么微任务执行更早:</p>\n<p>①Call Steak 清空(一次轮询结束)<br>②执行当前微任务<br>③尝试DOM渲染<br>④触发Event Loop<br>⑤执行宏任务</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">async</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">async1</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'async1 start'</span>) <span class=\"comment\">// 2</span></span><br><span class=\"line\"> <span class=\"keyword\">await</span> async2()</span><br><span class=\"line\"> <span class=\"comment\">// 异步 微任务 Promise then</span></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'async1 end'</span>) <span class=\"comment\">// 6</span></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">async</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">async2</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'async2'</span>) <span class=\"comment\">// 3</span></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"string\">'script start'</span>) <span class=\"comment\">// 1</span></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"comment\">// 异步 宏任务 setTimeout</span></span><br><span class=\"line\"><span class=\"built_in\">setTimeout</span>(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'setTimeout'</span>) <span class=\"comment\">// 8</span></span><br><span class=\"line\">}, <span class=\"number\">0</span>)</span><br><span class=\"line\"></span><br><span class=\"line\">async1()</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"comment\">// 初始化Promise时传入的函数会被立即执行</span></span><br><span class=\"line\"><span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span> (<span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\">resolve</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'promise1'</span>) <span class=\"comment\">// 4</span></span><br><span class=\"line\"> resolve()</span><br><span class=\"line\">}).then(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{ <span class=\"comment\">// 异步 微任务 Promise then</span></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'promise2'</span>) <span class=\"comment\">// 7</span></span><br><span class=\"line\">})</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"string\">'script end'</span>) <span class=\"comment\">// 5</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-json与对象相互转化","url":"/2021/02/01/JavaScript-json%E4%B8%8E%E5%AF%B9%E8%B1%A1%E7%9B%B8%E4%BA%92%E8%BD%AC%E5%8C%96/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-JSON转对象\"><a href=\"#1-JSON转对象\" class=\"headerlink\" title=\"1.JSON转对象\"></a>1.JSON转对象</h1><p>JSON.parse()</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"HTML\"><figure class=\"iseeu highlight /html\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">data-info</span>=<span class=\"string\">'{"name": "CalDey", "age": 25}'</span>></span><span class=\"tag\"></<span class=\"name\">div</span>></span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// JSON.parse() -> JSON转对象</span></span><br><span class=\"line\"><span class=\"keyword\">var</span> oDiv = <span class=\"built_in\">document</span>.getElementsByTagName(<span class=\"string\">'div'</span>)[<span class=\"number\">0</span>],</span><br><span class=\"line\"> info = oDiv.getAttribute(<span class=\"string\">'data-info'</span>);</span><br><span class=\"line\"> </span><br><span class=\"line\"><span class=\"keyword\">var</span> jsonData = <span class=\"built_in\">JSON</span>.parse(info);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(jsonData);</span><br><span class=\"line\"><span class=\"comment\">// {name: "CalDey", age: 25}</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"2-对象转JSON\"><a href=\"#2-对象转JSON\" class=\"headerlink\" title=\"2.对象转JSON\"></a>2.对象转JSON</h1><p>JSON.stringify()</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"HTML\"><figure class=\"iseeu highlight /html\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"tag\"><<span class=\"name\">div</span>></span><span class=\"tag\"></<span class=\"name\">div</span>></span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// JSON.stringify() -> 对象转JSON</span></span><br><span class=\"line\"><span class=\"keyword\">var</span> oDiv = <span class=\"built_in\">document</span>.getElementsByTagName(<span class=\"string\">'div'</span>)[<span class=\"number\">0</span>];</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">var</span> obj = {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span>,</span><br><span class=\"line\"> age: <span class=\"number\">23</span></span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">var</span> str = <span class=\"built_in\">JSON</span>.stringify(obj);</span><br><span class=\"line\">oDiv.setAttribute(<span class=\"string\">'data-info'</span>, str);</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-两张图弄懂基本类型和引用类型的复制过程","url":"/2020/12/17/JavaScript-%E4%B8%A4%E5%BC%A0%E5%9B%BE%E5%BC%84%E6%87%82%E5%9F%BA%E6%9C%AC%E7%B1%BB%E5%9E%8B%E5%92%8C%E5%BC%95%E7%94%A8%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%A4%8D%E5%88%B6%E8%BF%87%E7%A8%8B/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-基本类型值的复制\"><a href=\"#1-基本类型值的复制\" class=\"headerlink\" title=\"1.基本类型值的复制\"></a>1.基本类型值的复制</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> num1 = <span class=\"number\">5</span>;</span><br><span class=\"line\"><span class=\"keyword\">var</span> num2 = num1;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(num1, num2); <span class=\"comment\">// 5,5</span></span><br><span class=\"line\"><span class=\"keyword\">var</span> num2 = <span class=\"number\">50</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(num1, num2); <span class=\"comment\">// 5,50</span></span><br></pre></td></tr></table></figure></div>\n\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/%E5%9F%BA%E6%9C%AC%E7%B1%BB%E5%9E%8B.PNG\"></p>\n<p>我们设置num1中的值为5,声明一个新变量num2复制num1中的值,num2的值也是5,但这两个5是相互独立,互不影响的,如果我们修改num2中的值,num1的值不会发生改变。</p>\n<hr>\n<h1 id=\"2-引用类型值的复制\"><a href=\"#2-引用类型值的复制\" class=\"headerlink\" title=\"2.引用类型值的复制\"></a>2.引用类型值的复制</h1><p>相比于基本类型来说,引用类型稍显复杂:</p>\n<p>与基本类型不同,基本类型存储的是值,而引用类型存储的是地址(指针)</p>\n<p>基本类型值保存在栈(steak)中,而引用类型的值是由保存在栈内存(steak)的引用地址指向堆内存(heap)中存储的对象。当对象创建后,计算机会在内存中开辟一个空间存放数据,而我们要想访问到这个空间,就需要一个指向这个地址的指针。</p>\n<p>我们结合图片和代码分析整个过程:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> Obj1 = {};</span><br><span class=\"line\"><span class=\"keyword\">var</span> Obj2 = Obj1;</span><br><span class=\"line\">Obj2.name = <span class=\"string\">'CalDey'</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(Obj1.name) <span class=\"comment\">// CalDey</span></span><br></pre></td></tr></table></figure></div>\n\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/%E5%BC%95%E7%94%A8%E7%B1%BB%E5%9E%8B.PNG\"></p>\n<p>从图中我们可以看出,复制前的Obj1和复制后的Obj2的储存在栈内存中的值都是一个引用地址,指向堆内存中同一个对象。当我们改变对象的属性,Obj1和Obj2的值都会发生改变:当为Obj2添加name属性后,可以通过Obj1来访问这个这个属性。</p>\n<p>为什么这样设计?</p>\n<p>基本类型数据相对来说非常小,可以直接在栈中存储,且不会影响性能。但引用类型如JSON,能够存储许多数据,直接存储在栈中复制过程缓慢,影响性能</p>\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-什么是闭包?","url":"/2020/12/17/JavaScript-%E4%BB%80%E4%B9%88%E6%98%AF%E9%97%AD%E5%8C%85%EF%BC%9F/","content":"<p>什么是闭包?</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-函数作用域\"><a href=\"#1-函数作用域\" class=\"headerlink\" title=\"1.函数作用域\"></a>1.函数作用域</h1><p>要理解闭包,我们首先要理解js的变量作用域。</p>\n<p>变量作用域分为全局作用域和函数作用域:</p>\n<ul>\n<li>全局作用域在页面打开时被创建,页面关闭时被销毁</li>\n<li>函数作用域在函数调用时被创建,函数执行完毕后被销毁</li>\n</ul>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">myName</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"comment\">// 变量提升 var name</span></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a); <span class=\"comment\">// undefined</span></span><br><span class=\"line\"> {</span><br><span class=\"line\"> <span class=\"keyword\">var</span> a = <span class=\"string\">'CalDey'</span>;</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a); <span class=\"comment\">// CalDey</span></span><br><span class=\"line\">}</span><br><span class=\"line\">myName();</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(a) <span class=\"comment\">// Uncaught ReferenceError: a is not defined</span></span><br></pre></td></tr></table></figure></div>\n\n<p>ES6新增块级作用域:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">{</span><br><span class=\"line\"> <span class=\"keyword\">let</span> a = <span class=\"number\">123</span>;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a); <span class=\"comment\">// 123</span></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(a) <span class=\"comment\">// Uncaught ReferenceError: a is not defined</span></span><br></pre></td></tr></table></figure></div>\n\n<p>函数内部可以直接读取全局变量,而在函数外部不能读取函数内局部变量:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> p1 = <span class=\"string\">'CalDey'</span>;</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">person</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(p1); <span class=\"comment\">// CalDey</span></span><br><span class=\"line\"> <span class=\"keyword\">var</span> p2 = <span class=\"string\">'Tom'</span>;</span><br><span class=\"line\">};</span><br><span class=\"line\">person();</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(p2); <span class=\"comment\">// p2 is not defined</span></span><br></pre></td></tr></table></figure></div>\n\n<blockquote>\n<p>注意:如果函数内部声明变量忘记var,会声明一个全局变量</p>\n</blockquote>\n<hr>\n<h1 id=\"2-如何从外部读取局部变量?\"><a href=\"#2-如何从外部读取局部变量?\" class=\"headerlink\" title=\"2.如何从外部读取局部变量?\"></a>2.如何从外部读取局部变量?</h1><p>在一些特殊情况下,我们需要得到函数内的局部变量,正常情况下这是不可行的,为了达成目的,我们在函数内部再次定义一个函数:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">fn1</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">var</span> a = <span class=\"number\">123</span>;</span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">fn2</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a);</span><br><span class=\"line\"> }</span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"keyword\">return</span> fn2;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">var</span> res = fn1();</span><br><span class=\"line\">res(); <span class=\"comment\">// 123</span></span><br></pre></td></tr></table></figure></div>\n\n<p>上面代码中,fn2位于fn1的内部,这是fn1内部所有局部变量,对于fn2来说都是可见的,反之不行,fn2的变量对于fn1是不可见的。这是js的链式作用域,子对象会一级级的向上寻找父对象变量。我们通过将fn2作为返回值,就可以实现在外部读取内部变量。</p>\n<hr>\n<h1 id=\"3-什么是闭包\"><a href=\"#3-什么是闭包\" class=\"headerlink\" title=\"3.什么是闭包\"></a>3.什么是闭包</h1><p>上述代码中的fn2函数,其实就是闭包。我们可以简单的把闭包理解为“定义在函数内部的函数”,闭包本质上是链接函数内部和外部的桥梁。</p>\n<h1 id=\"4-闭包的作用\"><a href=\"#4-闭包的作用\" class=\"headerlink\" title=\"4.闭包的作用\"></a>4.闭包的作用</h1><p>闭包主要的两个用途,一是读取函数内部的变量,二是让变量值一直保存在内存中。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">fn1</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">var</span> n = <span class=\"number\">999</span>;</span><br><span class=\"line\"></span><br><span class=\"line\"> fnAdd = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> n += <span class=\"number\">1</span></span><br><span class=\"line\"> }</span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">fn2</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(n)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> fn2;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">var</span> res = fn1();</span><br><span class=\"line\">res(); <span class=\"comment\">// 999</span></span><br><span class=\"line\">fnAdd();</span><br><span class=\"line\">res(); <span class=\"comment\">// 1000</span></span><br></pre></td></tr></table></figure></div>\n\n<p>前文中我们得知,当函数执行完成后变量就会销毁,但上面的代码中变量n的值在函数执行完成后仍然保留在内存中,这是为什么?</p>\n<p>原因在于fn1是fn2的父函数,由于fn2被赋给一个全局变量,导致fn2一直在内存中,fn2依赖于fn1,因此fn1也一直保存在内存中。</p>\n<blockquote>\n<p>注意:我们可以注意到,fnAdd没有使用var关键字,它是一个全局变量,同时它还是一个匿名函数,匿名函数本身也是一个闭包,所以可以在函数外部对函数内部进行操作</p>\n</blockquote>\n<hr>\n<h1 id=\"5-一道面试题\"><a href=\"#5-一道面试题\" class=\"headerlink\" title=\"5.一道面试题\"></a>5.一道面试题</h1><p>我们通过一道面试题再来巩固一下闭包:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">for</span> (<span class=\"keyword\">var</span> i = <span class=\"number\">1</span>; i <= <span class=\"number\">5</span>; i++) {</span><br><span class=\"line\"> <span class=\"built_in\">setTimeout</span>(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">timer</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(i)</span><br><span class=\"line\"> }, i * <span class=\"number\">1000</span>)</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>setTimeout是异步函数,会先把循环全部执行,结果全部输出6</p>\n<p>我们通过闭包的方式解决这个问题:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">for</span> (<span class=\"keyword\">var</span> i = <span class=\"number\">1</span>; i <= <span class=\"number\">5</span>; i++) {</span><br><span class=\"line\"> (<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">j</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">setTimeout</span>(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">timer</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(j)</span><br><span class=\"line\"> }, j * <span class=\"number\">1000</span>)</span><br><span class=\"line\"> })(i)</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<blockquote>\n<p>内容参考自:<br><a href=\"http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html\">学习Javascript闭包(Closure)</a><br><a href=\"https://juejin.cn/book/6844733763675488269/section/6844733763759374350\">前端面试之道</a><br><a href=\"https://zhuanlan.zhihu.com/p/22486908?refer=study-fe\">「每日一题」JS 中的闭包是什么?</a></p>\n</blockquote>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-从输入url到渲染出页面的整个过程","url":"/2021/02/22/JavaScript-%E4%BB%8E%E8%BE%93%E5%85%A5url%E5%88%B0%E6%B8%B2%E6%9F%93%E5%87%BA%E9%A1%B5%E9%9D%A2%E7%9A%84%E6%95%B4%E4%B8%AA%E8%BF%87%E7%A8%8B/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-从输入url到渲染出页面的整个过程\"><a href=\"#1-从输入url到渲染出页面的整个过程\" class=\"headerlink\" title=\"1.从输入url到渲染出页面的整个过程\"></a>1.从输入url到渲染出页面的整个过程</h1><p>加载过程</p>\n<ul>\n<li>查找缓存</li>\n<li>DNS解析:域名 -> ip地址</li>\n<li>浏览器根据IP地址向服务器发起http请求</li>\n<li>服务器处理http请求,并返回给浏览器<br>渲染过程</li>\n<li>根据HTML代码生成DOM Tree(文档对象模型)</li>\n<li>根据CSS代码生成CSSOM(CSS对象模型)</li>\n<li>将DOM Tree和CSSOM整合成Render Tree</li>\n<li>根据Render Tree渲染页面</li>\n<li>遇到<Script>暂停渲染,并优先执行JS代码</li>\n<li>Render Tree渲染完成</li>\n</ul>\n<hr>\n<h1 id=\"2-为什么建议将link放到head里?\"><a href=\"#2-为什么建议将link放到head里?\" class=\"headerlink\" title=\"2.为什么建议将link放到head里?\"></a>2.为什么建议将link放到head里?</h1><p>从上向下渲染,根据CSS的代码生成CSSOM,渲染过程中遇到CSS代码会重新生成一个CSSOM</p>\n<p>避免重复渲染</p>\n<hr>\n<h1 id=\"3-window-onload和DOMContentLoaded\"><a href=\"#3-window-onload和DOMContentLoaded\" class=\"headerlink\" title=\"3.window.onload和DOMContentLoaded\"></a>3.window.onload和DOMContentLoaded</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">window</span>.addEventListener(<span class=\"string\">'load'</span>, <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"comment\">// 页面资源全部加载完后执行,包括图片和视频</span></span><br><span class=\"line\">})</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">document</span>.addEventListener(<span class=\"string\">'DOMContentLoaded'</span>, <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"comment\">// DOM渲染完成后即可执行,此时图片和视频可能还没有加载完成</span></span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-内置对象数组","url":"/2021/01/08/JavaScript-%E5%86%85%E7%BD%AE%E5%AF%B9%E8%B1%A1%E6%95%B0%E7%BB%84/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<p>可以通过Array.prototype查看数组一共有多少种内置方法:</p>\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/Array.prototype.PNG\"></p>\n<p>下面我们来一一介绍这些方法</p>\n<hr>\n<h1 id=\"1-Array方法\"><a href=\"#1-Array方法\" class=\"headerlink\" title=\"1.Array方法\"></a>1.Array方法</h1><h2 id=\"1-1-Array-from\"><a href=\"#1-1-Array-from\" class=\"headerlink\" title=\"1.1.Array.from()\"></a>1.1.Array.from()</h2><p>从一个类数组或可迭代对象中创建一个新的,浅拷贝数组实例</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"built_in\">Array</span>.from(<span class=\"string\">'helloworld'</span>)) <span class=\"comment\">// h,e,l,l,o,w,o,r,l,d</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"built_in\">Array</span>.from([<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>], <span class=\"function\"><span class=\"params\">x</span>=></span> x + x)) <span class=\"comment\">// 2,4,6</span></span><br></pre></td></tr></table></figure></div>\n\n<p>可以通过Array.from()将类数组转化为数组:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arrayLike = {</span><br><span class=\"line\"> <span class=\"number\">0</span>: <span class=\"string\">'es6'</span>,</span><br><span class=\"line\"> <span class=\"number\">1</span>: <span class=\"string\">'es7'</span>,</span><br><span class=\"line\"> <span class=\"number\">2</span>: <span class=\"string\">'es8'</span>,</span><br><span class=\"line\"> length: <span class=\"number\">3</span></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">let</span> arr = <span class=\"built_in\">Array</span>.from(arrayLike)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr <span class=\"keyword\">instanceof</span> <span class=\"built_in\">Array</span>) <span class=\"comment\">// true</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"1-2-Array-isArray\"><a href=\"#1-2-Array-isArray\" class=\"headerlink\" title=\"1.2.Array.isArray()\"></a>1.2.Array.isArray()</h2><p>判断一个某个变量是否是数组对象</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"built_in\">Array</span>.isArray([<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>])) <span class=\"comment\">// true</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"1-3-Array-of\"><a href=\"#1-3-Array-of\" class=\"headerlink\" title=\"1.3.Array.of()\"></a>1.3.Array.of()</h2><p>创建一个拥有不定参数的新数组,且不考虑参数的类型</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr1 = <span class=\"keyword\">new</span> <span class=\"built_in\">Array</span>(<span class=\"number\">1</span>, <span class=\"number\">2</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr1) <span class=\"comment\">// [1, 2]</span></span><br><span class=\"line\"><span class=\"keyword\">let</span> arr2 = <span class=\"keyword\">new</span> <span class=\"built_in\">Array</span>(<span class=\"number\">3</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr2) <span class=\"comment\">// [empty * 3]</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"built_in\">Array</span>.of(<span class=\"number\">3</span>)) <span class=\"comment\">// [3]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"built_in\">Array</span>.of(<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>)) <span class=\"comment\">// [1,2,3]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"built_in\">Array</span>.of(<span class=\"literal\">undefined</span>)) <span class=\"comment\">// [undefined]</span></span><br></pre></td></tr></table></figure></div>\n\n<blockquote>\n<p>注意:Array(3)会创建出一个长度为3的空数组,而Array.of(3)会创建一个单元素3的数组</p>\n</blockquote>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = <span class=\"built_in\">Array</span>.of(<span class=\"number\">1</span>, <span class=\"literal\">true</span>, <span class=\"string\">'CalDey'</span>, [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>], {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span></span><br><span class=\"line\">})</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr)</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"2-Array-prototype方法\"><a href=\"#2-Array-prototype方法\" class=\"headerlink\" title=\"2.Array.prototype方法\"></a>2.Array.prototype方法</h1><p>所有数组实例都通过原型链从Array.prototype继承属性和方法,这些方法主要分为两种,修改原数组值的方法和不会修改原数组值的方法,下面来分别介绍:</p>\n<h2 id=\"2-1-会修改属性值的方法\"><a href=\"#2-1-会修改属性值的方法\" class=\"headerlink\" title=\"2.1.会修改属性值的方法\"></a>2.1.会修改属性值的方法</h2><ul>\n<li>增加:unshift()/push()</li>\n<li>删除:shift()/pop()</li>\n<li>修改:splice()/fill()</li>\n<li>翻转:reverse()</li>\n<li>排序:sort()</li>\n</ul>\n<h3 id=\"2-1-1-push\"><a href=\"#2-1-1-push\" class=\"headerlink\" title=\"2.1.1.push()\"></a>2.1.1.push()</h3><p>在数组<font color=#ff503e><strong>末尾</strong></font>添加一个或多个元素,并返回新数组的<font color=#ff503e><strong>长度</strong></font>,<font color=#ff503e><strong>会修改原数组</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>]</span><br><span class=\"line\"><span class=\"keyword\">let</span> num = arr.push(<span class=\"number\">4</span>,<span class=\"number\">5</span>,<span class=\"number\">6</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(num) <span class=\"comment\">// 6</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [1,2,3,4,5,6]</span></span><br></pre></td></tr></table></figure></div>\n\n<p>实现push方法:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">Array</span>.prototype.myPush = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">for</span> (<span class=\"keyword\">var</span> i = <span class=\"number\">0</span>; i < <span class=\"built_in\">arguments</span>.length; i++) {</span><br><span class=\"line\"> <span class=\"built_in\">this</span>[<span class=\"built_in\">this</span>.length] = <span class=\"built_in\">arguments</span>[i];</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"built_in\">this</span>.length;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>];</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.myPush(<span class=\"number\">4</span>,<span class=\"number\">5</span>,<span class=\"number\">6</span>)); <span class=\"comment\">// 6</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr); <span class=\"comment\">// [1,2,3,4,5,6]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-1-2-unshift\"><a href=\"#2-1-2-unshift\" class=\"headerlink\" title=\"2.1.2.unshift()\"></a>2.1.2.unshift()</h3><p>添加一个或多个元素到数组的<font color=#ff503e><strong>首部</strong></font>,并返回新数组的<font color=#ff503e><strong>长度</strong></font>,<font color=#ff503e><strong>会修改原数组</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>];</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.unshift(<span class=\"number\">4</span>,<span class=\"number\">5</span>)) <span class=\"comment\">// 5</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [4,5,1,2,3]</span></span><br></pre></td></tr></table></figure></div>\n\n<p>实现unshift方法:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">Array</span>.prototype.myUnshift = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">var</span> pos = <span class=\"number\">0</span>;</span><br><span class=\"line\"> <span class=\"keyword\">for</span> (<span class=\"keyword\">var</span> i = <span class=\"number\">0</span>; i < <span class=\"built_in\">arguments</span>.length; i++) {</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.splice(pos, <span class=\"number\">0</span> ,<span class=\"built_in\">arguments</span>[i]);</span><br><span class=\"line\"> pos++;</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"built_in\">this</span>.length;</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>];</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.myUnshift(<span class=\"number\">4</span>,<span class=\"number\">5</span>,<span class=\"number\">6</span>)); <span class=\"comment\">// 6</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr); <span class=\"comment\">// [4,5,6,1,2,3]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-1-3-pop\"><a href=\"#2-1-3-pop\" class=\"headerlink\" title=\"2.1.3.pop()\"></a>2.1.3.pop()</h3><p>从数组中删除<font color=#ff503e><strong>最后</strong></font>一个元素的值,然后返回<font color=#ff503e><strong>被删除元素的值</strong></font>,<font color=#ff503e><strong>会修改原数组</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>,<span class=\"number\">4</span>,<span class=\"number\">5</span>]</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.pop()) <span class=\"comment\">// 5</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [1,2,3,4]</span></span><br><span class=\"line\">arr.pop()</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [1,2,3]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-1-4-shift\"><a href=\"#2-1-4-shift\" class=\"headerlink\" title=\"2.1.4.shift()\"></a>2.1.4.shift()</h3><p>删除数组<font color=#ff503e><strong>第一个元素</strong></font>,并返回这个元素,<font color=#ff503e><strong>会修改原数组</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>]</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.shift()) <span class=\"comment\">// 1</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [2,3]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-1-5-reverse\"><a href=\"#2-1-5-reverse\" class=\"headerlink\" title=\"2.1.5.reverse()\"></a>2.1.5.reverse()</h3><p>翻转数组,<font color=#ff503e><strong>会修改原数组</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>]</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.reverse()) <span class=\"comment\">// [3,2,1]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [3,2,1]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-1-6-splice\"><a href=\"#2-1-6-splice\" class=\"headerlink\" title=\"2.1.6.splice()\"></a>2.1.6.splice()</h3><p>arr.splice(开始下标,剪切长度,添加新元素…)</p>\n<p>替换删除或添加元素来修改数组,<font color=#ff503e><strong>会修改原数组</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>,<span class=\"number\">4</span>]</span><br><span class=\"line\"><span class=\"comment\">// 删除</span></span><br><span class=\"line\">arr.splice(<span class=\"number\">1</span>,<span class=\"number\">2</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr); <span class=\"comment\">// [1, 4]</span></span><br><span class=\"line\"><span class=\"comment\">// 替换</span></span><br><span class=\"line\">arr.splice(<span class=\"number\">0</span>,<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr); <span class=\"comment\">// [2, 3, 4]</span></span><br><span class=\"line\"><span class=\"comment\">// 添加</span></span><br><span class=\"line\">arr.splice(<span class=\"number\">0</span>,<span class=\"number\">0</span>,<span class=\"number\">1</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr); <span class=\"comment\">// [1, 2, 3, 4]</span></span><br><span class=\"line\">arr.splice(<span class=\"number\">1</span>,<span class=\"number\">0</span>,<span class=\"string\">'a'</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr); <span class=\"comment\">// [1, a, 2, 3, 4]</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"string\">'a'</span>, <span class=\"string\">'b'</span>, <span class=\"string\">'c'</span>, <span class=\"string\">'e'</span>];</span><br><span class=\"line\">arr.splice(<span class=\"number\">3</span>,<span class=\"number\">0</span>,<span class=\"string\">'d'</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr); <span class=\"comment\">// [a, b, c, d, e]</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"string\">'a'</span>, <span class=\"string\">'b'</span>, <span class=\"string\">'c'</span>, <span class=\"string\">'e'</span>];</span><br><span class=\"line\">arr.splice(-<span class=\"number\">1</span>,<span class=\"number\">0</span>,<span class=\"string\">'d'</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr); <span class=\"comment\">// [a, b, c, d, e]</span></span><br></pre></td></tr></table></figure></div>\n\n<p>splice获取下标:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>, <span class=\"number\">4</span>, <span class=\"number\">5</span>];</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">splice</span>(<span class=\"params\">arr, index</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> index += index >= <span class=\"number\">0</span> ? <span class=\"number\">0</span> : arr.length;</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(splice(arr, -<span class=\"number\">1</span>));</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr[splice(arr, -<span class=\"number\">1</span>)]); <span class=\"comment\">// 5</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-1-7-sort\"><a href=\"#2-1-7-sort\" class=\"headerlink\" title=\"2.1.7.sort()\"></a>2.1.7.sort()</h3><p>对数组进行排序,并返回当前数组,<font color=#ff503e><strong>会修改原数组</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">3</span>,<span class=\"number\">2</span>,<span class=\"number\">6</span>,<span class=\"number\">4</span>,<span class=\"number\">1</span>,-<span class=\"number\">1</span>]</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.sort()) <span class=\"comment\">// [-1,1,2,3,4,6]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [-1,1,2,3,4,6]</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"string\">'a'</span>, <span class=\"string\">'d'</span>, <span class=\"string\">'c'</span>, <span class=\"string\">'b'</span>, <span class=\"string\">'e'</span>]</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.sort()) <span class=\"comment\">// [a,b,c,d,e]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [a,b,c,d,e]</span></span><br></pre></td></tr></table></figure></div>\n\n<p>这种排序方法并不总是有效的:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">24</span>, <span class=\"number\">42</span>, <span class=\"number\">1</span>, <span class=\"number\">100000</span>, <span class=\"number\">5</span>, <span class=\"number\">7</span>];</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.sort()); <span class=\"comment\">// [1,100000,24,42,5,7]</span></span><br></pre></td></tr></table></figure></div>\n\n<blockquote>\n<p>sort -> 按照ASCII码排序</p>\n</blockquote>\n<p>那么如何解决复杂数组sort乱序问题?</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">24</span>, <span class=\"number\">42</span>, <span class=\"number\">1</span>, <span class=\"number\">100000</span>, <span class=\"number\">5</span>, <span class=\"number\">7</span>];</span><br><span class=\"line\">arr.sort(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">a,b</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (a > b) {</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"number\">1</span>;</span><br><span class=\"line\"> } <span class=\"keyword\">else</span> {</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><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr); <span class=\"comment\">// [1,5,7,24,42,100000]</span></span><br></pre></td></tr></table></figure></div>\n\n<p>进一步简化:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">24</span>, <span class=\"number\">42</span>, <span class=\"number\">1</span>, <span class=\"number\">100000</span>, <span class=\"number\">5</span>, <span class=\"number\">7</span>];</span><br><span class=\"line\">arr.sort(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">a,b</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> a - b</span><br><span class=\"line\">});</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr);</span><br></pre></td></tr></table></figure></div>\n\n<p>自定义排序:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> arr = [</span><br><span class=\"line\"> {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span>,</span><br><span class=\"line\"> age: <span class=\"number\">23</span></span><br><span class=\"line\"> },</span><br><span class=\"line\"> {</span><br><span class=\"line\"> name: <span class=\"string\">'Tom'</span>,</span><br><span class=\"line\"> age: <span class=\"number\">20</span></span><br><span class=\"line\"> },</span><br><span class=\"line\"> {</span><br><span class=\"line\"> name: <span class=\"string\">'Lisa'</span>,</span><br><span class=\"line\"> age: <span class=\"number\">18</span></span><br><span class=\"line\"> },</span><br><span class=\"line\"> {</span><br><span class=\"line\"> name: <span class=\"string\">'Thomas'</span>,</span><br><span class=\"line\"> age: <span class=\"number\">27</span></span><br><span class=\"line\"> }</span><br><span class=\"line\">];</span><br><span class=\"line\"></span><br><span class=\"line\">arr.sort(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (a.age > b.age) {</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"number\">1</span>;</span><br><span class=\"line\"> } <span class=\"keyword\">else</span> {</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><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr);</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"string\">'12345'</span>, <span class=\"string\">'1'</span>, <span class=\"string\">'123'</span>, <span class=\"string\">'1234567'</span>];</span><br><span class=\"line\">arr.sort(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(a.length > b.length) {</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"number\">1</span>;</span><br><span class=\"line\"> } <span class=\"keyword\">else</span> {</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><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr); <span class=\"comment\">// [1,123,12345,1234567]</span></span><br></pre></td></tr></table></figure></div>\n\n<p>随机排序:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>, <span class=\"number\">4</span>, <span class=\"number\">5</span>];</span><br><span class=\"line\"><span class=\"comment\">// Math.random() -> 0~1</span></span><br><span class=\"line\">arr.sort(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">var</span> rand = <span class=\"built_in\">Math</span>.random();</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (rand > <span class=\"number\">0.5</span>) {</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"number\">1</span>;</span><br><span class=\"line\"> } <span class=\"keyword\">else</span> {</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><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr);</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-1-8-fill\"><a href=\"#2-1-8-fill\" class=\"headerlink\" title=\"2.1.8.fill()\"></a>2.1.8.fill()</h3><p>用一个固定值填充数组从起始索引到终止索引的值,<font color=#ff503e><strong>不包括终止索引,原数组会改变</strong></font></p>\n<p>arr.fill(固定值,起始索引,结束索引(不包括终止索引))</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>,<span class=\"number\">4</span>]</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.fill(<span class=\"number\">0</span>,<span class=\"number\">1</span>,<span class=\"number\">4</span>)) <span class=\"comment\">// [1,0,0,0]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.fill(<span class=\"number\">6</span>)) <span class=\"comment\">// [6,6,6,6]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [6,6,6,6]</span></span><br></pre></td></tr></table></figure></div>\n\n<p>填充空数组</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = <span class=\"keyword\">new</span> <span class=\"built_in\">Array</span>(<span class=\"number\">3</span>).fill(<span class=\"number\">7</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [7, 7, 7]</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>, <span class=\"number\">4</span>, <span class=\"number\">5</span>]</span><br><span class=\"line\">arr.fill(<span class=\"string\">'CalDey'</span>, <span class=\"number\">1</span>, <span class=\"number\">3</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [1, "CalDey", "CalDey", 4, 5]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-1-9-copyWithin\"><a href=\"#2-1-9-copyWithin\" class=\"headerlink\" title=\"2.1.9.copyWithin()\"></a>2.1.9.copyWithin()</h3><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 从索引为x元素开始替换,替换成从索引y开始的内容</span></span><br><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>, <span class=\"number\">4</span>, <span class=\"number\">5</span>]</span><br><span class=\"line\"><span class=\"comment\">// arr.copyWithin(1, 3)</span></span><br><span class=\"line\"><span class=\"comment\">// console.log(arr) // [1, 4, 5, 4, 5]</span></span><br><span class=\"line\"><span class=\"comment\">// arr.copyWithin(1, 2)</span></span><br><span class=\"line\"><span class=\"comment\">// console.log(arr) // [1, 3, 4, 5, 5]</span></span><br><span class=\"line\">arr.copyWithin(<span class=\"number\">1</span>, <span class=\"number\">4</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [1, 5, 3, 4, 5]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"2-2-不会修改原数组的方法\"><a href=\"#2-2-不会修改原数组的方法\" class=\"headerlink\" title=\"2.2.不会修改原数组的方法\"></a>2.2.不会修改原数组的方法</h2><h3 id=\"2-2-1-concat\"><a href=\"#2-2-1-concat\" class=\"headerlink\" title=\"2.2.1.concat()\"></a>2.2.1.concat()</h3><p>返回一个由当前数组和若干个其他数组组成的新数组,<font color=#1C90F3><strong>不会修改原数组</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>]</span><br><span class=\"line\">arr2 = arr.concat([<span class=\"number\">2</span>,<span class=\"number\">3</span>],[<span class=\"number\">666</span>])</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr2) <span class=\"comment\">// 1,2,3,2,3,666</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// 1,2,3 </span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-2-2-slice\"><a href=\"#2-2-2-slice\" class=\"headerlink\" title=\"2.2.2.slice()\"></a>2.2.2.slice()</h3><p>返回一个新数组,是由begin和end决定的对原数组的浅拷贝,数组中包括begin不包括end,<font color=#1C90F3><strong>不会修改原数组</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>,<span class=\"number\">4</span>,<span class=\"number\">5</span>]</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.slice()) <span class=\"comment\">// [1,2,3,4,5]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.slice(<span class=\"number\">2</span>)) <span class=\"comment\">// [3,4,5]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.slice(<span class=\"number\">2</span>,<span class=\"number\">4</span>)) <span class=\"comment\">// [3,4]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [1,2,3,4,5]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-2-3-join\"><a href=\"#2-2-3-join\" class=\"headerlink\" title=\"2.2.3.join()\"></a>2.2.3.join()</h3><p>将一个数组的所有元素连接成一个字符串并返回这个字符串,<font color=#1C90F3><strong>不会修改原数组</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"string\">'hello'</span>,<span class=\"string\">'world'</span>]</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.join()) <span class=\"comment\">// 'hello,world'</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"keyword\">typeof</span> arr.join()) <span class=\"comment\">// string</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.join(<span class=\"string\">'-'</span>)) <span class=\"comment\">// 'hello-world'</span></span><br></pre></td></tr></table></figure></div>\n\n<p>join和split连用:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"string\">'a'</span>, <span class=\"string\">'b'</span>, <span class=\"string\">'c'</span>,<span class=\"string\">'d'</span>]</span><br><span class=\"line\"><span class=\"keyword\">let</span> str1 = arr.join(<span class=\"string\">'-'</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(str1); <span class=\"comment\">// a-b-c-d</span></span><br><span class=\"line\"><span class=\"keyword\">let</span> arr1 = str1.split(<span class=\"string\">'-'</span>, <span class=\"number\">2</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr1); <span class=\"comment\">// [a,b]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-2-4-includes\"><a href=\"#2-2-4-includes\" class=\"headerlink\" title=\"2.2.4.includes()\"></a>2.2.4.includes()</h3><p>判断一个数组是否含有某一特定值,根据情况返回true或者false,<font color=#1C90F3><strong>不会修改原数组</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>]</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.includes(<span class=\"number\">1</span>)) <span class=\"comment\">// true</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.includes(<span class=\"number\">4</span>)) <span class=\"comment\">// false</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [1,2,3]</span></span><br></pre></td></tr></table></figure></div>\n\n<p>indexOf不能检测数组中是否包含NaN,includes可以</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>, <span class=\"literal\">NaN</span>]</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.indexOf(<span class=\"literal\">NaN</span>))</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"literal\">NaN</span> == <span class=\"literal\">NaN</span>) <span class=\"comment\">// false</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.includes(<span class=\"literal\">NaN</span>)) <span class=\"comment\">// true</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-2-5-toString\"><a href=\"#2-2-5-toString\" class=\"headerlink\" title=\"2.2.5.toString()\"></a>2.2.5.toString()</h3><p>返回数组的字符串形式,<font color=#1C90F3><strong>不会修改原数组</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>,<span class=\"number\">4</span>,<span class=\"number\">5</span>]</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.toString()) <span class=\"comment\">// '1,2,3,4,5'</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"keyword\">typeof</span> arr.toString()) <span class=\"comment\">// string</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-2-6-indexOf\"><a href=\"#2-2-6-indexOf\" class=\"headerlink\" title=\"2.2.6.indexOf()\"></a>2.2.6.indexOf()</h3><p>返回一个指定元素在数组中的第一个索引,不存在返回-1,<font color=#1C90F3><strong>不会修改原数组</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"string\">'mike'</span>,<span class=\"string\">'xiaoming'</span>,<span class=\"string\">'lisa'</span>,<span class=\"string\">'miya'</span>]</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.indexOf(<span class=\"string\">'mike'</span>)) <span class=\"comment\">// 0</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.indexOf(<span class=\"string\">'CalDey'</span>)) <span class=\"comment\">// -1</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"2-3-遍历方法\"><a href=\"#2-3-遍历方法\" class=\"headerlink\" title=\"2.3.遍历方法\"></a>2.3.遍历方法</h2><p>在下面这些遍历方法中,有许多方法需要指定一个回调函数作为参数</p>\n<h3 id=\"2-3-1-forEach\"><a href=\"#2-3-1-forEach\" class=\"headerlink\" title=\"2.3.1.forEach()\"></a>2.3.1.forEach()</h3><p>循环遍历数组,类似于for循环</p>\n<p>常规的for循环:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>]</span><br><span class=\"line\"><span class=\"keyword\">for</span>(<span class=\"keyword\">let</span> i = <span class=\"number\">0</span>; i < arr.length; i++){</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(arr[i]) <span class=\"comment\">// 1, 2, 3</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>通过forEach也能达到同样效果,且语法更简洁,不需要通过索引访问对应元素</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>]</span><br><span class=\"line\">arr.forEach(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">elem, index, array</span>)</span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(elem) <span class=\"comment\">// 1, 2, 3</span></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(index) <span class=\"comment\">// 0, 1, 2</span></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(array) <span class=\"comment\">// [1, 2, 3],[1, 2, 3],[1, 2, 3]</span></span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure></div>\n\n<p>但forEach与for相比并非没有缺点,forEach没有返回值,遍历过程不能中途跳出循环,因此也不能使用break和contibue</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">[<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>].forEach(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">i</span>)</span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(i === <span class=\"number\">2</span>){</span><br><span class=\"line\"> <span class=\"keyword\">return</span></span><br><span class=\"line\"> }<span class=\"keyword\">else</span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(i) <span class=\"comment\">// 1, 3</span></span><br><span class=\"line\"> }</span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>]</span><br><span class=\"line\">arr.forEach(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">elem, index, array</span>)</span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(arr[i] = <span class=\"number\">2</span>){</span><br><span class=\"line\"> <span class=\"keyword\">break</span></span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(arr[i]) <span class=\"comment\">// 报错</span></span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>]</span><br><span class=\"line\">arr.forEach(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">elem, index, array</span>)</span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(arr[i] = <span class=\"number\">2</span>){</span><br><span class=\"line\"> <span class=\"keyword\">continue</span></span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(arr[i]) <span class=\"comment\">// 报错</span></span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-3-2-map\"><a href=\"#2-3-2-map\" class=\"headerlink\" title=\"2.3.2.map()\"></a>2.3.2.map()</h3><p>创建一个新数组,其结果是该数组中每个元素调用一次提供函数后的返回值,<font color=#ff503e><strong>不会修改原数组</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>]</span><br><span class=\"line\"><span class=\"keyword\">let</span> res = arr.map(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">value</span>)</span>{</span><br><span class=\"line\"> value += <span class=\"number\">1</span></span><br><span class=\"line\"> <span class=\"keyword\">return</span> value</span><br><span class=\"line\">})</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [1, 2, 3]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(res) <span class=\"comment\">// [2, 3, 4]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-3-3-filter\"><a href=\"#2-3-3-filter\" class=\"headerlink\" title=\"2.3.3.filter()\"></a>2.3.3.filter()</h3><p>创建一个新数组,其包含的元素是通过filter提供的函数测试通过后的元素</p>\n<p><font color=#ff503e><strong>通俗的讲,就是对数组元素进行指定条件的筛选</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>]</span><br><span class=\"line\"><span class=\"keyword\">let</span> res = arr.filter(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">value</span>)</span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> value == <span class=\"number\">2</span></span><br><span class=\"line\">})</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [1, 2, 3]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(res) <span class=\"comment\">// [2]</span></span><br></pre></td></tr></table></figure></div>\n\n<p>筛选数组中所有长度大于4的元素:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"string\">'CalDey'</span>,<span class=\"string\">'mike'</span>,<span class=\"string\">'lisa'</span>,<span class=\"string\">'Misaki'</span>,<span class=\"string\">'Abraham'</span>] </span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.filter(<span class=\"function\"><span class=\"params\">element</span> =></span> element.length > <span class=\"number\">4</span>)) <span class=\"comment\">// CalDey,Misaki,Abraham</span></span><br></pre></td></tr></table></figure></div>\n\n<p>自定义函数对数组进行筛选:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">100</span>,<span class=\"number\">456</span>,<span class=\"number\">1234</span>,<span class=\"number\">645</span>,<span class=\"number\">23</span>,<span class=\"number\">65</span>,<span class=\"number\">88</span>,<span class=\"number\">17</span>,<span class=\"number\">632</span>,<span class=\"number\">3</span>]</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">isBigEnough</span>(<span class=\"params\">element</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> element > <span class=\"number\">100</span></span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.filter(isBigEnough)) <span class=\"comment\">// 456,1234,645,632</span></span><br></pre></td></tr></table></figure></div>\n\n<p>筛选json中的有效数据:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [</span><br><span class=\"line\"> {<span class=\"attr\">id</span> : <span class=\"number\">1</span>},</span><br><span class=\"line\"> {<span class=\"attr\">id</span> : <span class=\"number\">123</span>},</span><br><span class=\"line\"> {<span class=\"attr\">id</span> : -<span class=\"number\">1</span>},</span><br><span class=\"line\"> {<span class=\"attr\">id</span> : <span class=\"number\">0</span>},</span><br><span class=\"line\"> {<span class=\"attr\">id</span> : <span class=\"number\">3.14</span>},</span><br><span class=\"line\"> {},</span><br><span class=\"line\"> {<span class=\"attr\">id</span> : <span class=\"literal\">null</span>},</span><br><span class=\"line\"> {<span class=\"attr\">id</span> : <span class=\"literal\">undefined</span>},</span><br><span class=\"line\"> {<span class=\"attr\">id</span> : <span class=\"literal\">NaN</span>}</span><br><span class=\"line\">]</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">let</span> errorNum = <span class=\"number\">0</span>;</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">isNumber</span>(<span class=\"params\">obj</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> obj != <span class=\"literal\">undefined</span> && <span class=\"keyword\">typeof</span>(obj) === <span class=\"string\">'number'</span> && !<span class=\"built_in\">isNaN</span>(obj)</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">filterById</span>(<span class=\"params\">item</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (isNumber(item.id)) {</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"literal\">true</span></span><br><span class=\"line\"> }</span><br><span class=\"line\"> errorNum++;</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 class=\"keyword\">let</span> newArr = arr.filter(filterById)</span><br><span class=\"line\"></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"string\">'筛选后的数据:'</span> + newArr.forEach(<span class=\"function\"><span class=\"params\">element</span> =></span> <span class=\"built_in\">console</span>.log(element)))</span><br><span class=\"line\"><span class=\"comment\">// {id : 1} {id : 123} {id : -1} {id : 0} {id : 3.14}</span></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"string\">'筛选掉的数据:'</span> + errorNum) <span class=\"comment\">// 4</span></span><br></pre></td></tr></table></figure></div>\n\n<p>实现简单的搜索功能:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> animals = [<span class=\"string\">'Monkey'</span>, <span class=\"string\">'Cat'</span>, <span class=\"string\">'dog'</span>, <span class=\"string\">'Giraffe'</span>, <span class=\"string\">'zebra'</span>]</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">filterItems</span>(<span class=\"params\">query</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> animals.filter(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">el</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> el.toLowerCase().indexOf(query.toLowerCase()) > -<span class=\"number\">1</span></span><br><span class=\"line\"> })</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(filterItems(<span class=\"string\">'a'</span>)) <span class=\"comment\">// [Cat,Giraffe,zebra]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(filterItems(<span class=\"string\">'m'</span>)) <span class=\"comment\">// [Monkey]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(filterItems(<span class=\"string\">'q'</span>)) <span class=\"comment\">// []</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-3-4-some\"><a href=\"#2-3-4-some\" class=\"headerlink\" title=\"2.3.4.some()\"></a>2.3.4.some()</h3><p>与filter类似,对数组进行筛选,但返回结果为布尔类型,只要有一个元素符合筛选条件就返回true</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>]</span><br><span class=\"line\"><span class=\"keyword\">let</span> res = arr.some(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">value</span>)</span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> value == <span class=\"number\">2</span></span><br><span class=\"line\">})</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [1, 2, 3]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(res) <span class=\"comment\">// true</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-3-5-every\"><a href=\"#2-3-5-every\" class=\"headerlink\" title=\"2.3.5.every()\"></a>2.3.5.every()</h3><p>与filter类似,对数组进行筛选,但返回结果为布尔类型,只有所有元素全部符合筛选条件就才返回true</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>]</span><br><span class=\"line\"><span class=\"keyword\">let</span> res = arr.every(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">value</span>)</span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> value == <span class=\"number\">2</span></span><br><span class=\"line\">})</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr) <span class=\"comment\">// [1, 2, 3]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(res) <span class=\"comment\">// false</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-3-6-reduce\"><a href=\"#2-3-6-reduce\" class=\"headerlink\" title=\"2.3.6.reduce()\"></a>2.3.6.reduce()</h3><p>reduce接收一个函数作为累加器</p>\n<p>求和</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>]</span><br><span class=\"line\"><span class=\"keyword\">let</span> sum = arr.reduce(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">prev, cur, index, array</span>)</span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> prev + cur</span><br><span class=\"line\">}, </span><br><span class=\"line\"><span class=\"number\">0</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(sum)</span><br></pre></td></tr></table></figure></div>\n\n<p>求最大值</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">5</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>, <span class=\"number\">7</span>, <span class=\"number\">1</span>]</span><br><span class=\"line\"><span class=\"keyword\">let</span> max = arr.reduce(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">prev, cur</span>)</span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"built_in\">Math</span>.max(prev, cur)</span><br><span class=\"line\">})</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(max) <span class=\"comment\">// 7</span></span><br></pre></td></tr></table></figure></div>\n\n<p>数组去重</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>,<span class=\"number\">2</span>,<span class=\"number\">1</span>]</span><br><span class=\"line\"><span class=\"keyword\">let</span> res = arr.reduce(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">prev,cur</span>)</span>{</span><br><span class=\"line\"> prev.indexOf(cur) == -<span class=\"number\">1</span> && prev.push(cur)</span><br><span class=\"line\"> <span class=\"keyword\">return</span> prev</span><br><span class=\"line\">},[])</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(res) <span class=\"comment\">// [1, 2, 3]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"2-3-7-for-…-in\"><a href=\"#2-3-7-for-…-in\" class=\"headerlink\" title=\"2.3.7.for … in ?\"></a>2.3.7.for … in ?</h3><p>除了for循环外,for … in 也可以遍历数组</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">0</span>, <span class=\"number\">1</span>, <span class=\"number\">2</span>]</span><br><span class=\"line\"><span class=\"keyword\">for</span>(<span class=\"keyword\">let</span> i <span class=\"keyword\">in</span> arr){</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(i) <span class=\"comment\">// 0 1 2</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>这种方法虽然能够成功遍历数组,但是并不推荐使用,因为for…in的设计初衷是遍历对象而非数组,如果数组上有自定义属性也会被遍历出来:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">Array</span>.prototype.say = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>)</span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'helloworld'</span>)</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">0</span>, <span class=\"number\">1</span>, <span class=\"number\">2</span>]</span><br><span class=\"line\"><span class=\"keyword\">for</span>(<span class=\"keyword\">let</span> i <span class=\"keyword\">in</span> arr){</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(i) <span class=\"comment\">// 0 1 2 say</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<blockquote>\n<p>本文章简单的介绍了大部分常用的数组api,如果想了解全部内置方法或进阶用法,<a href=\"https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array\">点击此处</a></p>\n</blockquote>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-同步和异步","url":"/2021/02/20/JavaScript-%E5%90%8C%E6%AD%A5%E5%92%8C%E5%BC%82%E6%AD%A5/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-同步和异步\"><a href=\"#1-同步和异步\" class=\"headerlink\" title=\"1.同步和异步\"></a>1.同步和异步</h1><p>JS是单线程语言,同一时间只能够做一件事</p>\n<p>类似生活中的去超市排队结账,正常情况下,一位收银员只能为一位顾客结账,其他顾客需要在后面排队等候</p>\n<p>为什么JS要设计成单线程?</p>\n<p>JS和DOM渲染公用同一线程,因为JS可以操作DOM,如果存在多线程,一个线程添加DOM节点,另一个线程删除这个节点,就会发生冲突</p>\n<p>但如果遇到定时任务或者ajax请求超时的时候,会发生阻塞,一直处于等待状态,因此,JS被设计成同步和异步</p>\n<p>同步:只有前一个任务执行完毕,才能执行后一个任务<br>异步:当同步任务执行到某个 WebAPI 时,就会触发异步操作,此时浏览器会单独开线程去处理这些异步任务。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 同步</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"number\">100</span>)</span><br><span class=\"line\">alert(<span class=\"number\">200</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"number\">300</span>)</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 异步(callback回调函数)</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"number\">100</span>)</span><br><span class=\"line\"><span class=\"built_in\">setTimeout</span>(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">200</span>)</span><br><span class=\"line\">}, <span class=\"number\">1000</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"number\">300</span>)</span><br></pre></td></tr></table></figure></div>\n\n<p>同步会阻塞代码执行,异步不会阻塞代码执行</p>\n<hr>\n<h1 id=\"2-异步的使用场景\"><a href=\"#2-异步的使用场景\" class=\"headerlink\" title=\"2.异步的使用场景\"></a>2.异步的使用场景</h1><p>网络请求:ajax图片加载<br>定时任务:setTimeout</p>\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-安全","url":"/2021/02/22/JavaScript-%E5%AE%89%E5%85%A8/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<p>常见的web前端攻击方式</p>\n<h1 id=\"1-XSS-跨站请求攻击\"><a href=\"#1-XSS-跨站请求攻击\" class=\"headerlink\" title=\"1.XSS 跨站请求攻击\"></a>1.XSS 跨站请求攻击</h1><p>博客网站,发表一篇博客,博客内容中嵌入script脚本</p>\n<p>脚本内容:获取cookie,发送到我的服务器(配合跨域)</p>\n<p>用户查看这篇博客,获取访问者的cookie信息</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"HTML\"><figure class=\"iseeu highlight /html\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"tag\"><<span class=\"name\">p</span>></span>博客内容<span class=\"tag\"></<span class=\"name\">p</span>></span></span><br><span class=\"line\"><span class=\"tag\"><<span class=\"name\">p</span>></span>博客内容<span class=\"tag\"></<span class=\"name\">p</span>></span></span><br><span class=\"line\"><span class=\"tag\"><<span class=\"name\">p</span>></span>博客内容<span class=\"tag\"></<span class=\"name\">p</span>></span></span><br><span class=\"line\"><span class=\"tag\"><<span class=\"name\">script</span>></span><span class=\"javascript\">alert(<span class=\"built_in\">document</span>.cookie)</span><span class=\"tag\"></<span class=\"name\">script</span>></span></span><br></pre></td></tr></table></figure></div>\n\n<p>预防:替换<>特殊字符</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"TXT\"><figure class=\"iseeu highlight /txt\"><table><tr><td class=\"code\"><pre><span class=\"line\">< 符号 -> &lt; </span><br><span class=\"line\">> 符号 -> &gt;</span><br></pre></td></tr></table></figure></div>\n\n<p>前后端都要替换</p>\n<hr>\n<h1 id=\"2-CSRF-跨站请求伪造\"><a href=\"#2-CSRF-跨站请求伪造\" class=\"headerlink\" title=\"2.CSRF 跨站请求伪造\"></a>2.CSRF 跨站请求伪造</h1><p>资源网站中虚拟货币付费接口,没有任何验证</p>\n<p>img标签可以跨域,引导登录用户点击图片,其内容指向付费链接</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"HTML\"><figure class=\"iseeu highlight /html\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"tag\"><<span class=\"name\">img</span> <span class=\"attr\">src</span>=<span class=\"string\">xxx.com/pay?id</span>=<span class=\"string\">200</span> /></span></span><br></pre></td></tr></table></figure></div>\n\n<p>预防:使用POST接口(POST想要跨域需要后端认证)</p>\n<p>增加用户验证(密码,短信验证码)</p>\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-性能优化","url":"/2021/02/22/JavaScript-%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-性能优化原则\"><a href=\"#1-性能优化原则\" class=\"headerlink\" title=\"1.性能优化原则\"></a>1.性能优化原则</h1><p>多使用内存,缓存或其他方法</p>\n<p>减少CPU计算量,减少网络加载耗时</p>\n<p>(所有编程的性能优化 -> 空间换时间)</p>\n<hr>\n<h1 id=\"2-性能优化角度\"><a href=\"#2-性能优化角度\" class=\"headerlink\" title=\"2.性能优化角度\"></a>2.性能优化角度</h1><h2 id=\"2-1-让加载更快\"><a href=\"#2-1-让加载更快\" class=\"headerlink\" title=\"2.1.让加载更快\"></a>2.1.让加载更快</h2><p>减少资源体积:压缩代码/图片/视频<br>减少访问次数:合并代码(雪碧图合并图片),SSR服务器端渲染,缓存<br>使用CDN</p>\n<hr>\n<h2 id=\"2-2-让渲染更快\"><a href=\"#2-2-让渲染更快\" class=\"headerlink\" title=\"2.2.让渲染更快\"></a>2.2.让渲染更快</h2><p>CSS放在head,JS放在body后<br>用DOMContentLoaded触发<br>懒加载(图片懒加载,上滑显示更多)<br>缓存DOM查询<br>频繁DOM操作合并到一起插入DOM(document.createDocumentFragment())<br>节流(throttle)和防抖(debounce)</p>\n<hr>\n<h1 id=\"3-性能优化案例\"><a href=\"#3-性能优化案例\" class=\"headerlink\" title=\"3.性能优化案例\"></a>3.性能优化案例</h1><h2 id=\"3-1-资源合并\"><a href=\"#3-1-资源合并\" class=\"headerlink\" title=\"3.1.资源合并\"></a>3.1.资源合并</h2><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><script src=<span class=\"string\">"a.js"</span>></script></span><br><span class=\"line\"><script src=<span class=\"string\">"b.js"</span>></script></span><br><span class=\"line\"><script src=<span class=\"string\">"c.js"</span>></script></span><br><span class=\"line\"><span class=\"comment\">// 三次请求合并成一次请求</span></span><br><span class=\"line\"><script src=<span class=\"string\">"abc.js"</span>></script></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"3-2-缓存\"><a href=\"#3-2-缓存\" class=\"headerlink\" title=\"3.2.缓存\"></a>3.2.缓存</h2><p>webpack中给静态资源加hash后缀,根据文件内容计算hash值,文件不变hash不变</p>\n<p>url和文件不变,返回304,自动触发http缓存机制</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">module</span>.exports = {</span><br><span class=\"line\"> mode: <span class=\"string\">'production'</span>,</span><br><span class=\"line\"> entry: path.join(__dirname, <span class=\"string\">'src'</span>, <span class=\"string\">'index'</span>),</span><br><span class=\"line\"> output: {</span><br><span class=\"line\"> <span class=\"comment\">// 为静态生成hash后缀</span></span><br><span class=\"line\"> filename: <span class=\"string\">'bundle.[contenthash].js'</span>,</span><br><span class=\"line\"> path: path.join(__dirname, <span class=\"string\">'dist'</span>)</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"3-3-CDN\"><a href=\"#3-3-CDN\" class=\"headerlink\" title=\"3.3.CDN\"></a>3.3.CDN</h2><p>静态资源加速</p>\n<hr>\n<h2 id=\"3-4-SSR\"><a href=\"#3-4-SSR\" class=\"headerlink\" title=\"3.4.SSR\"></a>3.4.SSR</h2><p>服务器端渲染:将网页和数据一起加载一起渲染</p>\n<p>前后端分离:先加载网页,再加载数据,再渲染数据</p>\n<hr>\n<h2 id=\"3-5-图片懒加载\"><a href=\"#3-5-图片懒加载\" class=\"headerlink\" title=\"3.5.图片懒加载\"></a>3.5.图片懒加载</h2><p>先加载预览图,后加载真实图片</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><body></span><br><span class=\"line\"> <img src=<span class=\"string\">"preview.png"</span> data-realsrc=<span class=\"string\">"abc.png"</span>></span><br><span class=\"line\"></body></span><br><span class=\"line\"><script></span><br><span class=\"line\"> <span class=\"keyword\">var</span> img = <span class=\"built_in\">document</span>.getElementById(<span class=\"string\">'img'</span>);</span><br><span class=\"line\"> img.src = img.getAttribute(<span class=\"string\">'data-realsrc'</span>)</span><br><span class=\"line\"></script></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"3-6-DOM性能优化\"><a href=\"#3-6-DOM性能优化\" class=\"headerlink\" title=\"3.6.DOM性能优化\"></a>3.6.DOM性能优化</h2><p>缓存DOM查询<br>将频繁操作改为一次操作</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><body></span><br><span class=\"line\"> <ul id=<span class=\"string\">"list"</span>></ul></span><br><span class=\"line\"></body></span><br><span class=\"line\"><script></span><br><span class=\"line\"> <span class=\"keyword\">const</span> list = <span class=\"built_in\">document</span>.getElementById(<span class=\"string\">'list'</span>)</span><br><span class=\"line\"> <span class=\"keyword\">const</span> frag = <span class=\"built_in\">document</span>.createDocumentFragment()</span><br><span class=\"line\"> <span class=\"keyword\">for</span>(<span class=\"keyword\">let</span> i = <span class=\"number\">0</span>; i < <span class=\"number\">1000</span>; i++) {</span><br><span class=\"line\"> <span class=\"keyword\">const</span> li = <span class=\"built_in\">document</span>.createElement(<span class=\"string\">'li'</span>)</span><br><span class=\"line\"> li.innerHTML = <span class=\"string\">`list <span class=\"subst\">${i}</span>`</span></span><br><span class=\"line\"> <span class=\"comment\">// 大量DOM操作影响性能</span></span><br><span class=\"line\"> <span class=\"comment\">// list.appendChild(li)</span></span><br><span class=\"line\"> <span class=\"comment\">// frag不涉及DOM操作,不影响性能</span></span><br><span class=\"line\"> frag.appendChild(li)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"comment\">// 一次性插入</span></span><br><span class=\"line\"> list.appendChild(frag)</span><br><span class=\"line\"></script></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-手写代码","url":"/2021/03/05/JavaScript-%E6%89%8B%E5%86%99%E4%BB%A3%E7%A0%81/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-手写clearfix\"><a href=\"#1-手写clearfix\" class=\"headerlink\" title=\"1.手写clearfix\"></a>1.手写clearfix</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.clearfix</span><span class=\"selector-pseudo\">:after</span> {</span><br><span class=\"line\"> <span class=\"attribute\">content</span>: <span class=\"string\">''</span>;</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: block;</span><br><span class=\"line\"> <span class=\"attribute\">clear</span>: both;</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"comment\">/* 兼容低版本 */</span></span><br><span class=\"line\"><span class=\"selector-class\">.clearfix</span> {</span><br><span class=\"line\"> <span class=\"attribute\">*zoom</span>: <span class=\"number\">1</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"2-CSS画三角形\"><a href=\"#2-CSS画三角形\" class=\"headerlink\" title=\"2.CSS画三角形\"></a>2.CSS画三角形</h1><iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/a4aKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h1 id=\"3-圣杯布局和双飞翼布局\"><a href=\"#3-圣杯布局和双飞翼布局\" class=\"headerlink\" title=\"3.圣杯布局和双飞翼布局\"></a>3.圣杯布局和双飞翼布局</h1><p>圣杯布局</p>\n<iframe width=\"100%\" height=\"350\" src=\"//jsrun.net/aSwKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>双飞翼布局</p>\n<iframe width=\"100%\" height=\"350\" src=\"//jsrun.net/Y4wKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h1 id=\"4-手写instanceof\"><a href=\"#4-手写instanceof\" class=\"headerlink\" title=\"4.手写instanceof\"></a>4.手写instanceof</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> myInstanceof = <span class=\"function\">(<span class=\"params\">target, origin</span>) =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">while</span>(target) {</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (target.__proto__ === origin.prototype) {</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"literal\">true</span></span><br><span class=\"line\"> }</span><br><span class=\"line\"> target = target.__proto__</span><br><span class=\"line\"> }</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 class=\"keyword\">let</span> a = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>]</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(myInstanceof(a, <span class=\"built_in\">Array</span>))</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(myInstanceof(a, <span class=\"built_in\">Object</span>))</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(myInstanceof(a, <span class=\"built_in\">Function</span>))</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"5-手写new过程\"><a href=\"#5-手写new过程\" class=\"headerlink\" title=\"5.手写new过程\"></a>5.手写new过程</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">myNew</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"comment\">// 1.创建空对象</span></span><br><span class=\"line\"> <span class=\"keyword\">let</span> obj = {}</span><br><span class=\"line\"> <span class=\"comment\">// 获取构造函数</span></span><br><span class=\"line\"> <span class=\"keyword\">let</span> Con = [].shift.call(<span class=\"built_in\">arguments</span>)</span><br><span class=\"line\"> <span class=\"comment\">// 2.链接原型</span></span><br><span class=\"line\"> obj.__proto__ = Con.prototype</span><br><span class=\"line\"> <span class=\"comment\">// 3.绑定this</span></span><br><span class=\"line\"> <span class=\"keyword\">let</span> res = Con.apply(obj, <span class=\"built_in\">arguments</span>)</span><br><span class=\"line\"> <span class=\"comment\">// 4.返回对象</span></span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"keyword\">typeof</span> res <span class=\"keyword\">instanceof</span> <span class=\"built_in\">Object</span> ? res : obj</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Person</span>(<span class=\"params\">name, age</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.name = name,</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.age = age</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> p = myNew(Person, <span class=\"string\">'CalDey'</span>, <span class=\"number\">23</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(p)</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"6-手写call-apply-bind\"><a href=\"#6-手写call-apply-bind\" class=\"headerlink\" title=\"6.手写call,apply,bind\"></a>6.手写call,apply,bind</h1><p>bind</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">Function</span>.prototype.myBind = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">const</span> args = <span class=\"built_in\">Array</span>.prototype.slice.call(<span class=\"built_in\">arguments</span>)</span><br><span class=\"line\"> <span class=\"keyword\">const</span> t = args.shift()</span><br><span class=\"line\"> <span class=\"keyword\">const</span> _this = <span class=\"built_in\">this</span></span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> _this.apply(t,args)</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">fn1</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>);</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a, b)</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> fn2 = fn1.myBind({<span class=\"attr\">x</span>:<span class=\"number\">100</span>},<span class=\"number\">10</span>,<span class=\"number\">20</span>)</span><br><span class=\"line\">fn2()</span><br></pre></td></tr></table></figure></div>\n\n<p>call</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">Function</span>.prototype.myCall = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">t, ...args</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">const</span> _this = <span class=\"built_in\">this</span></span><br><span class=\"line\"> <span class=\"keyword\">return</span> (<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> _this.apply(t,args)</span><br><span class=\"line\"> })()</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">fn1</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>);</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a, b)</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> fn2 = fn1.myCall({<span class=\"attr\">x</span>:<span class=\"number\">100</span>},<span class=\"number\">10</span>,<span class=\"number\">20</span>)</span><br></pre></td></tr></table></figure></div>\n\n<p>apply</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">Function</span>.prototype.myApply = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">t, args</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">const</span> _this = <span class=\"built_in\">this</span></span><br><span class=\"line\"> <span class=\"keyword\">return</span> (<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> _this.call(t, ...args)</span><br><span class=\"line\"> })()</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">fn1</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>);</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a, b)</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> fn2 = fn1.myApply({<span class=\"attr\">x</span>:<span class=\"number\">100</span>},[<span class=\"number\">10</span>,<span class=\"number\">20</span>])</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"7-手写深浅拷贝\"><a href=\"#7-手写深浅拷贝\" class=\"headerlink\" title=\"7.手写深浅拷贝\"></a>7.手写深浅拷贝</h1><p>浅拷贝</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">myClone</span>(<span class=\"params\">target</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">let</span> cloneTarget = {}</span><br><span class=\"line\"> <span class=\"keyword\">for</span>(<span class=\"keyword\">let</span> key <span class=\"keyword\">in</span> target) {</span><br><span class=\"line\"> cloneTarget[key] = target[key]</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> cloneTarget</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> obj1 = {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span>,</span><br><span class=\"line\"> age: <span class=\"number\">23</span></span><br><span class=\"line\">} </span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> obj2 = myClone(obj1);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj1)</span><br><span class=\"line\">obj1.name = <span class=\"string\">'thomas'</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj1)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj2) </span><br></pre></td></tr></table></figure></div>\n\n<p>实现简易深拷贝</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">myDeepClone</span>(<span class=\"params\">target</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (<span class=\"keyword\">typeof</span> target === <span class=\"string\">'object'</span>) {</span><br><span class=\"line\"> <span class=\"keyword\">let</span> cloneTarget = <span class=\"built_in\">Array</span>.isArray(target) ? [] : {}</span><br><span class=\"line\"> <span class=\"keyword\">for</span>(<span class=\"keyword\">let</span> key <span class=\"keyword\">in</span> target) {</span><br><span class=\"line\"> cloneTarget[key] = myDeepClone(target[key])</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> cloneTarget</span><br><span class=\"line\"> } <span class=\"keyword\">else</span> {</span><br><span class=\"line\"> <span class=\"keyword\">return</span> target</span><br><span class=\"line\"> }</span><br><span class=\"line\"></span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> obj1 = {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span>,</span><br><span class=\"line\"> age: <span class=\"number\">23</span>,</span><br><span class=\"line\"> sayHi: {</span><br><span class=\"line\"> say: <span class=\"string\">'Hello'</span></span><br><span class=\"line\"> }</span><br><span class=\"line\">} </span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> obj2 = myDeepClone(obj1);</span><br><span class=\"line\">obj1.sayHi.say = <span class=\"string\">'helloworld'</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj1)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj2)</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"8-数组去重\"><a href=\"#8-数组去重\" class=\"headerlink\" title=\"8.数组去重\"></a>8.数组去重</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">0</span>, <span class=\"number\">0</span>, <span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>, <span class=\"number\">4</span>, <span class=\"number\">5</span>];</span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">unique</span>(<span class=\"params\">arr</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">let</span> newArr = [];</span><br><span class=\"line\"> <span class=\"keyword\">for</span> (<span class=\"keyword\">let</span> i = <span class=\"number\">0</span>; i < arr.length; i++) {</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (newArr.indexOf(arr[i]) < <span class=\"number\">0</span>) {</span><br><span class=\"line\"> newArr.push(arr[i])</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> newArr;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(unique(arr))</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> arr = [<span class=\"number\">0</span>,<span class=\"number\">0</span>,<span class=\"number\">0</span>,<span class=\"number\">1</span>,<span class=\"number\">1</span>,<span class=\"number\">1</span>,<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>,<span class=\"number\">3</span>,<span class=\"string\">'a'</span>,<span class=\"string\">'a'</span>];</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">Array</span>.prototype.unique = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">var</span> temp = {},</span><br><span class=\"line\"> newArr = [];</span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"keyword\">for</span>(<span class=\"keyword\">var</span> i = <span class=\"number\">0</span>; i < <span class=\"built_in\">this</span>.length; i++){</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (!temp.hasOwnProperty(<span class=\"built_in\">this</span>[i])) {</span><br><span class=\"line\"> temp[<span class=\"built_in\">this</span>[i]] = <span class=\"built_in\">this</span>[i];</span><br><span class=\"line\"> newArr.push(<span class=\"built_in\">this</span>[i]);</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> newArr;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">var</span> arr1 = arr.unique();</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr1); <span class=\"comment\">// [0, 1, 2, 3, "a"]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"9-数组排序-优化sort\"><a href=\"#9-数组排序-优化sort\" class=\"headerlink\" title=\"9.数组排序(优化sort)\"></a>9.数组排序(优化sort)</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">24</span>, <span class=\"number\">42</span>, <span class=\"number\">1</span>, <span class=\"number\">100000</span>, <span class=\"number\">5</span>, <span class=\"number\">7</span>];</span><br><span class=\"line\">arr.sort(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">a,b</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (a > b) {</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"number\">1</span>;</span><br><span class=\"line\"> } <span class=\"keyword\">else</span> {</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><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr); <span class=\"comment\">// [1,5,7,24,42,100000]</span></span><br></pre></td></tr></table></figure></div>\n\n<p>进一步优化</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">24</span>, <span class=\"number\">42</span>, <span class=\"number\">1</span>, <span class=\"number\">100000</span>, <span class=\"number\">5</span>, <span class=\"number\">7</span>];</span><br><span class=\"line\">arr.sort(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">a,b</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> a - b</span><br><span class=\"line\">});</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr);</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"10-数组扁平化-多维数组降为一维数组\"><a href=\"#10-数组扁平化-多维数组降为一维数组\" class=\"headerlink\" title=\"10.数组扁平化(多维数组降为一维数组)\"></a>10.数组扁平化(多维数组降为一维数组)</h1><p>核心思路:遍历arr,若arr[i]仍为数组则递归遍历,直到不为数组,最后使用concat合并结果</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">flatten</span>(<span class=\"params\">arr</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">let</span> newArr = [];</span><br><span class=\"line\"> arr.map(<span class=\"function\"><span class=\"params\">i</span> =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(<span class=\"built_in\">Array</span>.isArray(i)) {</span><br><span class=\"line\"> newArr = newArr.concat(flatten(i))</span><br><span class=\"line\"> } <span class=\"keyword\">else</span> {</span><br><span class=\"line\"> newArr.push(i)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> })</span><br><span class=\"line\"> <span class=\"keyword\">return</span> newArr</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, [<span class=\"number\">2</span>, <span class=\"number\">3</span>], [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>], [<span class=\"number\">1</span>]];</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(flatten(arr))</span><br></pre></td></tr></table></figure></div>\n\n<p>es6提供flat方法</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, [<span class=\"number\">2</span>, <span class=\"number\">3</span>], [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>], [<span class=\"number\">1</span>]];</span><br><span class=\"line\"><span class=\"keyword\">let</span> newArr = arr.flat();</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(newArr)</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"11-函数科里化\"><a href=\"#11-函数科里化\" class=\"headerlink\" title=\"11.函数科里化\"></a>11.函数科里化</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> curry = <span class=\"function\">(<span class=\"params\">fn, ...args</span>) =></span> args.length >= fn.length ? fn(...args) : <span class=\"function\">(<span class=\"params\">..._args</span>) =></span> curry(fn, ...args, ..._args)</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">add1</span>(<span class=\"params\">x, y, z</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> x + y + z</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> add = curry(add1)</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(add(<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>))</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(add(<span class=\"number\">1</span>)(<span class=\"number\">2</span>)(<span class=\"number\">3</span>))</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(add(<span class=\"number\">1</span>, <span class=\"number\">2</span>)(<span class=\"number\">3</span>))</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"12-封装Ajax\"><a href=\"#12-封装Ajax\" class=\"headerlink\" title=\"12.封装Ajax\"></a>12.封装Ajax</h1><p>GET</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest()</span><br><span class=\"line\">xhr.open(<span class=\"string\">'GET'</span>, <span class=\"string\">'./data.json'</span>, <span class=\"literal\">true</span>)</span><br><span class=\"line\">xhr.onreadystatechange = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(xhr.readyState === <span class=\"number\">4</span>) {</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(xhr.status === <span class=\"number\">200</span>) {</span><br><span class=\"line\"> alert(xhr.responseText)</span><br><span class=\"line\"> }<span class=\"keyword\">else</span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'err'</span>)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\">xhr.send(<span class=\"literal\">null</span>) </span><br></pre></td></tr></table></figure></div>\n\n<p>POST</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest()</span><br><span class=\"line\">xhr.open(<span class=\"string\">'POST'</span>, <span class=\"string\">'/login'</span>, <span class=\"literal\">true</span>)</span><br><span class=\"line\">xhr.onreadystatechange = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(xhr.readyState === <span class=\"number\">4</span>) {</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(xhr.status === <span class=\"number\">200</span>) {</span><br><span class=\"line\"> alert(xhr.responseText)</span><br><span class=\"line\"> }<span class=\"keyword\">else</span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'err'</span>)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">const</span> postData = {</span><br><span class=\"line\"> userName: <span class=\"string\">'CalDey'</span>,</span><br><span class=\"line\"> password: <span class=\"number\">123456</span></span><br><span class=\"line\">}</span><br><span class=\"line\">xhr.send(<span class=\"built_in\">JSON</span>.stringify(postData))</span><br></pre></td></tr></table></figure></div>\n\n<p>添加Promise</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">ajax</span>(<span class=\"params\">url</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">const</span> p = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">const</span> xhr = <span class=\"keyword\">new</span> XMLHttpRequest()</span><br><span class=\"line\"> xhr.open(<span class=\"string\">'GET'</span>, url, <span class=\"literal\">true</span>)</span><br><span class=\"line\"> xhr.onreadystatechange = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(xhr.readyState === <span class=\"number\">4</span>){</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(xhr.status === <span class=\"number\">200</span>){</span><br><span class=\"line\"> resolve(</span><br><span class=\"line\"> <span class=\"built_in\">JSON</span>.parse(xhr.responseText)</span><br><span class=\"line\"> )</span><br><span class=\"line\"> }<span class=\"keyword\">else</span> <span class=\"keyword\">if</span>(xhr.status === <span class=\"number\">404</span>) {</span><br><span class=\"line\"> reject(<span class=\"keyword\">new</span> <span class=\"built_in\">Error</span>(<span class=\"string\">'404 not found'</span>))</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\"> xhr.send(<span class=\"literal\">null</span>)</span><br><span class=\"line\"> })</span><br><span class=\"line\"> <span class=\"keyword\">return</span> p</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> url1 = <span class=\"string\">'./data.json'</span></span><br><span class=\"line\"><span class=\"keyword\">const</span> url2 = <span class=\"string\">'./data1.json'</span></span><br><span class=\"line\">ajax(url1).then(<span class=\"function\"><span class=\"params\">res</span> =></span> <span class=\"built_in\">console</span>.log(res)).catch(<span class=\"function\"><span class=\"params\">err</span> =></span> <span class=\"built_in\">console</span>.log(err))</span><br><span class=\"line\">ajax(url2).then(<span class=\"function\"><span class=\"params\">res</span> =></span> <span class=\"built_in\">console</span>.log(res)).catch(<span class=\"function\"><span class=\"params\">err</span> =></span> <span class=\"built_in\">console</span>.log(err))</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"13-手写防抖和节流\"><a href=\"#13-手写防抖和节流\" class=\"headerlink\" title=\"13.手写防抖和节流\"></a>13.手写防抖和节流</h1><p>防抖</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">debounce</span>(<span class=\"params\">fn, delay = <span class=\"number\">500</span></span>) </span>{</span><br><span class=\"line\"> <span class=\"comment\">// timer在闭包中</span></span><br><span class=\"line\"> <span class=\"keyword\">let</span> timer = <span class=\"literal\">null</span></span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (timer) {</span><br><span class=\"line\"> <span class=\"built_in\">clearTimeout</span>(timer)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> timer = <span class=\"built_in\">setTimeout</span>(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> fn.apply(<span class=\"built_in\">this</span>, <span class=\"built_in\">arguments</span>)</span><br><span class=\"line\"> timer = <span class=\"literal\">null</span></span><br><span class=\"line\"> }, delay)</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>节流</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">throttle</span>(<span class=\"params\">fn, delay = <span class=\"number\">100</span></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">let</span> timer = <span class=\"literal\">null</span></span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (timer) {</span><br><span class=\"line\"> <span class=\"keyword\">return</span></span><br><span class=\"line\"> }</span><br><span class=\"line\"> timer = <span class=\"built_in\">setTimeout</span>(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> fn.apply(<span class=\"built_in\">this</span>, <span class=\"built_in\">arguments</span>)</span><br><span class=\"line\"> timer = <span class=\"literal\">null</span></span><br><span class=\"line\"> }, delay)</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"14-手写Promise加载图片\"><a href=\"#14-手写Promise加载图片\" class=\"headerlink\" title=\"14.手写Promise加载图片\"></a>14.手写Promise加载图片</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">loadImg</span>(<span class=\"params\">src</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(</span><br><span class=\"line\"> (resolve, reject) => {</span><br><span class=\"line\"> <span class=\"keyword\">const</span> img = <span class=\"built_in\">document</span>.createElement(<span class=\"string\">'img'</span>)</span><br><span class=\"line\"> img.onload = <span class=\"function\">() =></span> {</span><br><span class=\"line\"> resolve(img)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> img.onerror = <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">const</span> err = <span class=\"keyword\">new</span> <span class=\"built_in\">Error</span>(<span class=\"string\">`图片加载失败 <span class=\"subst\">${src}</span>`</span>)</span><br><span class=\"line\"> reject(err)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> img.src = src</span><br><span class=\"line\"> }</span><br><span class=\"line\"> )</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> url1 = <span class=\"string\">'https://gitee.com/caldey/BlogImage/raw/master/img/avatar.jpg'</span></span><br><span class=\"line\"><span class=\"keyword\">const</span> url2 = <span class=\"string\">'https://gitee.com/caldey/BlogImage/raw/master/img/img.jpg'</span></span><br><span class=\"line\"></span><br><span class=\"line\">loadImg(url1).then(<span class=\"function\"><span class=\"params\">img1</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(img1.width)</span><br><span class=\"line\"> <span class=\"keyword\">return</span> img1</span><br><span class=\"line\">}).then(<span class=\"function\"><span class=\"params\">img1</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(img1.height)</span><br><span class=\"line\"> <span class=\"keyword\">return</span> loadImg(url2)</span><br><span class=\"line\">}).then(<span class=\"function\"><span class=\"params\">img2</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(img2.width)</span><br><span class=\"line\"> <span class=\"keyword\">return</span> img2</span><br><span class=\"line\">}).then(<span class=\"function\"><span class=\"params\">img2</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(img2.height)</span><br><span class=\"line\">}).catch(<span class=\"function\"><span class=\"params\">ex</span> =></span> <span class=\"built_in\">console</span>.error(ex))</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"15-setTimeout\"><a href=\"#15-setTimeout\" class=\"headerlink\" title=\"15.setTimeout\"></a>15.setTimeout</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">for</span>(<span class=\"keyword\">var</span> i = <span class=\"number\">0</span>; i < <span class=\"number\">10</span>; i++) {</span><br><span class=\"line\"> (<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">j</span>)</span>{</span><br><span class=\"line\"> <span class=\"built_in\">setTimeout</span>(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(j)</span><br><span class=\"line\"> }, <span class=\"number\">1000</span>)</span><br><span class=\"line\"> })(i)</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">for</span>(<span class=\"keyword\">let</span> i = <span class=\"number\">0</span>; i < <span class=\"number\">10</span>; i++) {</span><br><span class=\"line\"> <span class=\"built_in\">setTimeout</span>(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(i)</span><br><span class=\"line\"> }, <span class=\"number\">1000</span>)</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<h1 id=\"16-创建10个标签,点击弹出对应的序号\"><a href=\"#16-创建10个标签,点击弹出对应的序号\" class=\"headerlink\" title=\"16.创建10个标签,点击弹出对应的序号\"></a>16.创建10个标签,点击弹出对应的序号</h1><iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/qKNKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript","面试"]},{"title":"JavaScript-数组去重","url":"/2021/04/01/JavaScript-%E6%95%B0%E7%BB%84%E5%8E%BB%E9%87%8D/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-双重循环\"><a href=\"#1-双重循环\" class=\"headerlink\" title=\"1.双重循环\"></a>1.双重循环</h1><p>第一次循环循环数组arr,第二次循环循环去重后的新数组newArr,若arr[i] = newArr[j],说明该元素重复,break跳出循环;否则则说明该元素唯一,j =newArr.length,将该元素添加进新数组</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>,<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>,<span class=\"number\">3</span>]</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">unique</span>(<span class=\"params\">arr</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">let</span> newArr= []</span><br><span class=\"line\"> <span class=\"keyword\">for</span>(<span class=\"keyword\">var</span> i = <span class=\"number\">0</span>; i < arr.length; i++) {</span><br><span class=\"line\"> <span class=\"keyword\">for</span> (<span class=\"keyword\">var</span> j = <span class=\"number\">0</span>; j < newArr.length; j++) {</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (newArr[j] === arr[i]) {</span><br><span class=\"line\"> <span class=\"keyword\">break</span></span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (j === newArr.length) {</span><br><span class=\"line\"> newArr.push(arr[i])</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> newArr</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(unique(arr)) <span class=\"comment\">// [1, 2, 3]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"2-indexOf\"><a href=\"#2-indexOf\" class=\"headerlink\" title=\"2.indexOf\"></a>2.indexOf</h1><p>循环数组,通过indexOf判断每一个元素是否存在于新数组中,不存在则添加进新数组</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>,<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>,<span class=\"number\">3</span>]</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">unique</span>(<span class=\"params\">arr</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">let</span> newArr = []</span><br><span class=\"line\"> <span class=\"keyword\">for</span>(<span class=\"keyword\">let</span> i = <span class=\"number\">0</span>; i < arr.length; i++) {</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (newArr.indexOf(arr[i]) < <span class=\"number\">0</span>) {</span><br><span class=\"line\"> newArr.push(arr[i])</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> newArr</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(unique(arr)) <span class=\"comment\">// [1, 2, 3]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"3-sort\"><a href=\"#3-sort\" class=\"headerlink\" title=\"3.sort\"></a>3.sort</h1><p>数组先排序再去重,效率高于indexOf</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr1 = [<span class=\"number\">1</span>,<span class=\"number\">1</span>,<span class=\"number\">3</span>,<span class=\"number\">3</span>,<span class=\"number\">2</span>,<span class=\"number\">2</span>]</span><br><span class=\"line\"><span class=\"keyword\">let</span> arr2 = [<span class=\"number\">1</span>,<span class=\"number\">1</span>,<span class=\"number\">100</span>,<span class=\"number\">2</span>]</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">unique</span>(<span class=\"params\">arr</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">let</span> newArr = []</span><br><span class=\"line\"> arr = arr.sort(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> a - b</span><br><span class=\"line\"> })</span><br><span class=\"line\"> <span class=\"keyword\">for</span> (<span class=\"keyword\">let</span> i = <span class=\"number\">0</span>; i < arr.length; i++) {</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (arr[i] != arr[i+<span class=\"number\">1</span>]) {</span><br><span class=\"line\"> newArr.push(arr[i])</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> newArr</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(unique(arr1)) <span class=\"comment\">// [1, 2, 3]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(unique(arr2)) <span class=\"comment\">// [1, 2, 100]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"4-es6\"><a href=\"#4-es6\" class=\"headerlink\" title=\"4.es6\"></a>4.es6</h1><p>es6新增新的数据结构Set,其类似数组,值都是唯一的,通过Array.from将其转化成真正的数组即可快速实现数组去重</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>,<span class=\"number\">1</span>,<span class=\"number\">3</span>,<span class=\"number\">3</span>,<span class=\"number\">2</span>,<span class=\"number\">2</span>]</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">unique</span>(<span class=\"params\">arr</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"built_in\">Array</span>.from(<span class=\"keyword\">new</span> <span class=\"built_in\">Set</span>(arr))</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(unique(arr)) <span class=\"comment\">// [1, 3, 2]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<blockquote>\n<p>内容参考自:<a href=\"https://github.com/mqyqingfeng/Blog/issues/27\">JavaScript专题之数组去重</a></p>\n</blockquote>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-数组去重和字符串去重","url":"/2021/01/24/JavaScript-%E6%95%B0%E7%BB%84%E5%8E%BB%E9%87%8D%E5%92%8C%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%8E%BB%E9%87%8D/","content":"<p>面试常考题-数组去重和字符串去重</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-数组去重\"><a href=\"#1-数组去重\" class=\"headerlink\" title=\"1.数组去重\"></a>1.数组去重</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> arr = [<span class=\"number\">0</span>,<span class=\"number\">0</span>,<span class=\"number\">0</span>,<span class=\"number\">1</span>,<span class=\"number\">1</span>,<span class=\"number\">1</span>,<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>,<span class=\"number\">3</span>,<span class=\"string\">'a'</span>,<span class=\"string\">'a'</span>];</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">Array</span>.prototype.unique = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">var</span> temp = {},</span><br><span class=\"line\"> newArr = [];</span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"keyword\">for</span>(<span class=\"keyword\">var</span> i = <span class=\"number\">0</span>; i < <span class=\"built_in\">this</span>.length; i++){</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (!temp.hasOwnProperty(<span class=\"built_in\">this</span>[i])) {</span><br><span class=\"line\"> temp[<span class=\"built_in\">this</span>[i]] = <span class=\"built_in\">this</span>[i];</span><br><span class=\"line\"> newArr.push(<span class=\"built_in\">this</span>[i]);</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> newArr;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">var</span> arr1 = arr.unique();</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr1); <span class=\"comment\">// [0, 1, 2, 3, "a"]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"2-字符串去重\"><a href=\"#2-字符串去重\" class=\"headerlink\" title=\"2.字符串去重\"></a>2.字符串去重</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> str = <span class=\"string\">'1122234434444aabb'</span>;</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">String</span>.prototype.unique = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">var</span> temp = {},</span><br><span class=\"line\"> newArr = [];</span><br><span class=\"line\"> </span><br><span class=\"line\"> <span class=\"keyword\">for</span>(<span class=\"keyword\">var</span> i = <span class=\"number\">0</span>; i < <span class=\"built_in\">this</span>.length; i++) {</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(!temp.hasOwnProperty(<span class=\"built_in\">this</span>[i])) {</span><br><span class=\"line\"> temp[<span class=\"built_in\">this</span>[i]] = <span class=\"built_in\">this</span>[i];</span><br><span class=\"line\"> newArr += <span class=\"built_in\">this</span>[i];</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> newArr;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(str.unique()); <span class=\"comment\">// 1234ab</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-数组扁平化","url":"/2021/04/01/JavaScript-%E6%95%B0%E7%BB%84%E6%89%81%E5%B9%B3%E5%8C%96/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-递归\"><a href=\"#1-递归\" class=\"headerlink\" title=\"1.递归\"></a>1.递归</h1><p>循环数组,判断数组内元素是否仍为数组,通过递归将嵌套数组层层剥开,扁平化处理</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> arr = [<span class=\"number\">1</span>,[<span class=\"number\">1</span>,<span class=\"number\">3</span>],[<span class=\"number\">3</span>,<span class=\"number\">2</span>,[<span class=\"number\">2</span>]]]</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">flatten</span>(<span class=\"params\">arr</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">let</span> newArr = []</span><br><span class=\"line\"> <span class=\"keyword\">for</span> (<span class=\"keyword\">let</span> i = <span class=\"number\">0</span>; i < arr.length; i++) {</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (<span class=\"built_in\">Array</span>.isArray(arr[i])) {</span><br><span class=\"line\"> newArr = newArr.concat(flatten(arr[i]))</span><br><span class=\"line\"> } <span class=\"keyword\">else</span> {</span><br><span class=\"line\"> newArr.push(arr[i])</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> newArr</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(flatten(arr)) <span class=\"comment\">// [1, 1, 3, 3, 2, 2]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"2-展开运算符\"><a href=\"#2-展开运算符\" class=\"headerlink\" title=\"2.展开运算符\"></a>2.展开运算符</h1><p>es6新增的展开运算符可以用来扁平化一层数组,通过改进实现多层数组扁平化</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> arr = [<span class=\"number\">1</span>, [<span class=\"number\">2</span>, [<span class=\"number\">3</span>]], [<span class=\"number\">2</span>]]</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">flatten</span>(<span class=\"params\">arr</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">while</span>(arr.some(<span class=\"function\"><span class=\"params\">item</span> =></span> <span class=\"built_in\">Array</span>.isArray(item))) {</span><br><span class=\"line\"> arr = [].concat(...arr)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> arr</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(flatten(arr)) <span class=\"comment\">// [1, 2, 3, 2]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<blockquote>\n<p>内容参考自:<a href=\"https://github.com/mqyqingfeng/Blog/issues/36\">JavaScript专题之数组扁平化</a></p>\n</blockquote>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-浅析new命令的执行过程","url":"/2020/12/09/JavaScript-%E6%B5%85%E6%9E%90new%E5%91%BD%E4%BB%A4%E7%9A%84%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B/","content":"<p>本文简单的分析了在new命令执行的过程中发生了什么,以及如何自己封装一个new命令。</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-new命令的执行过程\"><a href=\"#1-new命令的执行过程\" class=\"headerlink\" title=\"1.new命令的执行过程\"></a>1.new命令的执行过程</h1><p>首先来看下面的代码,思考一下执行这段代码会发生什么?</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> Person = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">name, age</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.name = name;</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.age = age;</span><br><span class=\"line\">};</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">var</span> p = <span class=\"keyword\">new</span> Person(<span class=\"string\">"CalDey"</span>, <span class=\"number\">23</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(p);</span><br></pre></td></tr></table></figure></div>\n\n<p>很明显,这是通过new命令让构造函数Person生成了一个实例对象,我们用p保存对象,并输出这个对象的内容。</p>\n<p>我们来通过控制台来验证我们的结论是否正确:</p>\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/img1.PNG\"></p>\n<p>我们可以看到,输出结果里有属性name,age和每个对象都拥有的属性__proto__</p>\n<p>想要弄清楚new的执行过程,我们首先花一点时间来了解一下原型和原型链:</p>\n<p>当我们用obj(对象名).XXX的方式访问一个属性时,JavaScript引擎首先会在当前对象上查找该属性,如果没找到,就会到它的原型对象上去找,如果还没有找到,会一直层层查找直到Object.prototype对象,如果仍未找到属性,那么就会返回null,这个查找过程叫做原型链。</p>\n<p>下面举一个简单的例子:</p>\n<p>我们创建一个Array对象arr,通过reverse方法将其翻转:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> arr = [<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>];</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.reverse()); <span class=\"comment\">// 3,2,1</span></span><br></pre></td></tr></table></figure></div>\n\n<p>请注意,我们创建的arr对象本身是不包含reverse方法的,为什么它可以直接使用reverse方法呢?那么该方法只能来自它的原型对象上了,我们先看一下arr的原型链:</p>\n<p>arr -> Array.prototype -> Object.prototype -> null</p>\n<p>该方法不属于arr,那么首先会来到它的原型对象Array.prototype上查找,我们通过代码验证Array上是否存在reserse方法:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"built_in\">Array</span>.prototype);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.__proto__);</span><br></pre></td></tr></table></figure></div>\n\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/img2.PNG\"></p>\n<p>显然arr使用的reverse方法来源在其原型对象Array。</p>\n<hr>\n<p>现在我们对原型有了初步了解,那么回到正题,我们知道对象实例是通过new命令从构造函数获取属性的,实例对象本身是没有属性的。这是不是很像刚才arr的例子?回到最初的代码中验证一下我们的猜想:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(p);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(Person.prototype);</span><br></pre></td></tr></table></figure></div>\n\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/202012092146.PNG\"></p>\n<p>我们通过对比对象实例p的__proto__和构造函数的prototype,发现其结果完全一致。</p>\n<hr>\n<p>至此,我们已经大概了解了new命令创建对象的过程,大致可以分为4个步骤:</p>\n<ul>\n<li>创建一个空对象</li>\n<li>链接到原型(将创建的对象的__proto__属性设置为构造函数的prototype属性)</li>\n<li>绑定this(构造函数中this指向新对象并调用构造函数)</li>\n<li>返回新对象</li>\n</ul>\n<p>我们可以把new的过程看作以下过程:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> Person = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">name, age</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.name = name;</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.age = age;</span><br><span class=\"line\">};</span><br><span class=\"line\"><span class=\"comment\">// var p = new Person("CalDey", 23);</span></span><br><span class=\"line\"><span class=\"comment\">// console.log(p);</span></span><br><span class=\"line\"><span class=\"comment\">// 可以近似看作以下代码</span></span><br><span class=\"line\"><span class=\"keyword\">var</span> p = {};</span><br><span class=\"line\">p.__proto__ = Person.prototype;</span><br><span class=\"line\">Person.call(p, <span class=\"string\">'CalDey'</span>, <span class=\"number\">23</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(p)</span><br></pre></td></tr></table></figure></div>\n\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/202012092217.PNG\"></p>\n<p>可以看出,两种写法的结果一致。</p>\n<hr>\n<h1 id=\"2-自己封装一个new命令\"><a href=\"#2-自己封装一个new命令\" class=\"headerlink\" title=\"2.自己封装一个new命令\"></a>2.自己封装一个new命令</h1><p>我们已经知道了new命令执行的基本流程,下面我们就参考new的过程自己封装一个new命令:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Person</span>(<span class=\"params\">name, age</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.name = name;</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.age = age;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">myNew</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"comment\">// 1.创建一个空对象</span></span><br><span class=\"line\"> <span class=\"keyword\">let</span> obj = {};</span><br><span class=\"line\"> <span class=\"comment\">// 2.获取构造函数</span></span><br><span class=\"line\"> <span class=\"keyword\">let</span> Con = [].shift.call(<span class=\"built_in\">arguments</span>) <span class=\"comment\">// 将类数组arguments转换为数组,取出其中的第一个值作为构造函数</span></span><br><span class=\"line\"> <span class=\"comment\">// 3.链接到原型</span></span><br><span class=\"line\"> obj.__proto__ = Con.prototype;</span><br><span class=\"line\"> <span class=\"comment\">// 4.绑定this</span></span><br><span class=\"line\"> <span class=\"keyword\">let</span> result = Con.apply(obj, <span class=\"built_in\">arguments</span>) </span><br><span class=\"line\"> <span class=\"comment\">// 第一个参数替代构造函数Con中的this,第二个参数为数组作为参数传递给Con</span></span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"comment\">// 5.检查new是否为对象</span></span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"keyword\">typeof</span> result <span class=\"keyword\">instanceof</span> <span class=\"built_in\">Object</span> ? result : obj</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">var</span> p = myNew(Person, <span class=\"string\">'CalDey'</span>, <span class=\"string\">'23'</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(p);</span><br></pre></td></tr></table></figure></div>\n\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/202012092241.PNG\"></p>\n<p>我们完成了对new命令的重写,执行结果和new相同。</p>\n<hr>\n<blockquote>\n<p>内容参考自:<a href=\"https://www.cnblogs.com/memphis-f/p/12029567.html\">https://www.cnblogs.com/memphis-f/p/12029567.html</a></p>\n</blockquote>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-浅谈深浅拷贝","url":"/2020/12/17/JavaScript-%E6%B5%85%E8%B0%88%E6%B7%B1%E6%B5%85%E6%8B%B7%E8%B4%9D/","content":"<p>灵魂拷问:什么是浅拷贝?如何实现浅拷贝?什么是深拷贝?如何实现深拷贝?</p>\n<hr>\n<a id=\"more\"></a>\n\n<p>对于对象的复制,有不同的方法,除了我们提到过的变量赋值外,还有深拷贝和浅拷贝。</p>\n<h1 id=\"1-赋值,浅拷贝和深拷贝\"><a href=\"#1-赋值,浅拷贝和深拷贝\" class=\"headerlink\" title=\"1.赋值,浅拷贝和深拷贝\"></a>1.赋值,浅拷贝和深拷贝</h1><p>赋值:当我们将一个对象赋值给一个新变量时,复制的是该对象的地址,而不是数据,两个对象在内存中的地址相同,其中任何一个发生改变,都会改变其中的内容。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> obj1 = {</span><br><span class=\"line\"> person: {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span></span><br><span class=\"line\"> },</span><br><span class=\"line\"> age: <span class=\"number\">23</span></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">let</span> obj2 = obj1;</span><br><span class=\"line\">obj2.person.name = <span class=\"string\">'Tom'</span>;</span><br><span class=\"line\">obj2.age = <span class=\"string\">'123'</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj1) <span class=\"comment\">// {person: {name: "Tom"}, age: "123"}</span></span><br></pre></td></tr></table></figure></div>\n\n<p>浅拷贝:创建一个新对象,这个对象有原始对象属性值的精准的拷贝,如果属性是基本类型,拷贝的是基本类型值,如果属性是引用类型,拷贝的就是内存地址。浅拷贝只能解决第一层问题,如果对象中还有对象,就需要使用深拷贝了。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> obj1 = {</span><br><span class=\"line\"> person: {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span></span><br><span class=\"line\"> },</span><br><span class=\"line\"> age: <span class=\"number\">23</span></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">let</span> obj2 = <span class=\"built_in\">Object</span>.assign({}, obj1);</span><br><span class=\"line\">obj2.person.name = <span class=\"string\">'Tom'</span>;</span><br><span class=\"line\">obj2.age = <span class=\"string\">'123'</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj1) <span class=\"comment\">// {person: {name: "Tom"}, age: "23"}</span></span><br></pre></td></tr></table></figure></div>\n\n<p>深拷贝:将一个对象在内存中完整拷贝下来,开辟一个新空间存放新对象,修改新对象不会影响原对象</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> obj1 = {</span><br><span class=\"line\"> person: {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span></span><br><span class=\"line\"> },</span><br><span class=\"line\"> age: <span class=\"number\">23</span></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">let</span> obj2 = <span class=\"built_in\">JSON</span>.parse(<span class=\"built_in\">JSON</span>.stringify(obj1))</span><br><span class=\"line\">obj2.person.name = <span class=\"string\">'Tom'</span>;</span><br><span class=\"line\">obj2.age = <span class=\"string\">'123'</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj1.person.name) <span class=\"comment\">// CalDey</span></span><br></pre></td></tr></table></figure></div>\n\n<h1 id=\"2-浅拷贝实现方式\"><a href=\"#2-浅拷贝实现方式\" class=\"headerlink\" title=\"2.浅拷贝实现方式\"></a>2.浅拷贝实现方式</h1><h2 id=\"2-1-Object-assign\"><a href=\"#2-1-Object-assign\" class=\"headerlink\" title=\"2.1.Object.assign()\"></a>2.1.Object.assign()</h2><p>Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> obj1 = {</span><br><span class=\"line\"> person: {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span></span><br><span class=\"line\"> },</span><br><span class=\"line\"> age: <span class=\"number\">23</span></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">let</span> obj2 = <span class=\"built_in\">Object</span>.assign({}, obj1);</span><br><span class=\"line\">obj2.person.name = <span class=\"string\">'Tom'</span>;</span><br><span class=\"line\">obj2.age = <span class=\"string\">'123'</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj1) <span class=\"comment\">// {person: {name: "Tom"}, age: "23"}</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"2-2-展开运算符…\"><a href=\"#2-2-展开运算符…\" class=\"headerlink\" title=\"2.2.展开运算符…\"></a>2.2.展开运算符…</h2><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> obj1 = {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">let</span> obj2 = {...obj1</span><br><span class=\"line\">}</span><br><span class=\"line\">obj2.name = <span class=\"string\">'Tom'</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj1.name) <span class=\"comment\">// CalDey</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"2-3-lodash库的-clone方法\"><a href=\"#2-3-lodash库的-clone方法\" class=\"headerlink\" title=\"2.3.lodash库的_.clone方法\"></a>2.3.lodash库的_.clone方法</h2><iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/t3IKp/embedded/js/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h2 id=\"2-4-Array-prototype-concat\"><a href=\"#2-4-Array-prototype-concat\" class=\"headerlink\" title=\"2.4.Array.prototype.concat()\"></a>2.4.Array.prototype.concat()</h2><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span></span><br><span class=\"line\">}]</span><br><span class=\"line\"><span class=\"keyword\">let</span> arr2 = arr.concat();</span><br><span class=\"line\">arr2[<span class=\"number\">0</span>] = <span class=\"number\">12</span>;</span><br><span class=\"line\">arr2[<span class=\"number\">2</span>].name = <span class=\"string\">'Tom'</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr); <span class=\"comment\">// [1, 2, { name: 'Tom' }]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"2-5-Array-prototype-slice\"><a href=\"#2-5-Array-prototype-slice\" class=\"headerlink\" title=\"2.5.Array.prototype.slice()\"></a>2.5.Array.prototype.slice()</h2><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span></span><br><span class=\"line\">}]</span><br><span class=\"line\"><span class=\"keyword\">let</span> arr2 = arr.slice();</span><br><span class=\"line\">arr2[<span class=\"number\">0</span>] = <span class=\"number\">12</span>;</span><br><span class=\"line\">arr2[<span class=\"number\">2</span>].name = <span class=\"string\">'Tom'</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr); <span class=\"comment\">// [1, 2, { name: 'Tom' }]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"3-深拷贝的实现方式\"><a href=\"#3-深拷贝的实现方式\" class=\"headerlink\" title=\"3.深拷贝的实现方式\"></a>3.深拷贝的实现方式</h1><h2 id=\"3-1-JSON-parse-JSON-stringify\"><a href=\"#3-1-JSON-parse-JSON-stringify\" class=\"headerlink\" title=\"3.1.JSON.parse(JSON.stringify())\"></a>3.1.JSON.parse(JSON.stringify())</h2><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> obj1 = {</span><br><span class=\"line\"> person: {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span></span><br><span class=\"line\"> },</span><br><span class=\"line\"> age: <span class=\"number\">23</span></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">let</span> obj2 = <span class=\"built_in\">JSON</span>.parse(<span class=\"built_in\">JSON</span>.stringify(obj1))</span><br><span class=\"line\">obj2.person.name = <span class=\"string\">'Tom'</span>;</span><br><span class=\"line\">obj2.age = <span class=\"string\">'123'</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj1.person.name) <span class=\"comment\">// CalDey</span></span><br></pre></td></tr></table></figure></div>\n\n<p>通过JSON.stringify将对象转化为JSON字符串,再用JSON.parse把字符串解析成对象,这样便生成了一个新对象。</p>\n<p>该方法有局限性:</p>\n<ul>\n<li>会忽略 undefined</li>\n<li>会忽略 symbol</li>\n<li>不能序列化函数</li>\n<li>不能解决循环引用的对象</li>\n</ul>\n<hr>\n<h2 id=\"3-2-lodash库的-cloneDeep方法-推荐\"><a href=\"#3-2-lodash库的-cloneDeep方法-推荐\" class=\"headerlink\" title=\"3.2.lodash库的_.cloneDeep方法(推荐)\"></a>3.2.lodash库的_.cloneDeep方法(推荐)</h2><iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/n3IKp/embedded/js/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h1 id=\"4-手写简单的浅拷贝和深拷贝\"><a href=\"#4-手写简单的浅拷贝和深拷贝\" class=\"headerlink\" title=\"4.手写简单的浅拷贝和深拷贝\"></a>4.手写简单的浅拷贝和深拷贝</h1><h2 id=\"4-1-浅拷贝\"><a href=\"#4-1-浅拷贝\" class=\"headerlink\" title=\"4.1.浅拷贝\"></a>4.1.浅拷贝</h2><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">myClone</span>(<span class=\"params\">target</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">let</span> cloneTarget = {};</span><br><span class=\"line\"> <span class=\"keyword\">for</span> (<span class=\"keyword\">const</span> key <span class=\"keyword\">in</span> target) {</span><br><span class=\"line\"> cloneTarget[key] = target[key];</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> cloneTarget</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"comment\">// test</span></span><br><span class=\"line\"><span class=\"keyword\">let</span> obj1 = {</span><br><span class=\"line\"> person: {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span></span><br><span class=\"line\"> },</span><br><span class=\"line\"> age: <span class=\"number\">23</span></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">let</span> obj2 = myClone(obj1);</span><br><span class=\"line\">obj2.person.name = <span class=\"string\">'Tom'</span>;</span><br><span class=\"line\">obj2.age = <span class=\"string\">'123'</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj1) <span class=\"comment\">// {person: {name: "Tom"}, age: "23"}</span></span><br></pre></td></tr></table></figure></div>\n\n<p>创建一个新对象,遍历需要克隆的对象,将属性依次添加到新对象上,返回新对象。</p>\n<hr>\n<h2 id=\"4-2-简易的深拷贝\"><a href=\"#4-2-简易的深拷贝\" class=\"headerlink\" title=\"4.2.简易的深拷贝\"></a>4.2.简易的深拷贝</h2><p>想要实现一个深拷贝,我们首先要清楚浅拷贝和深拷贝的区别,浅拷贝只能解决第一层的问题,我们并不清楚具体会有多少层的对象嵌套,所以我们通过递归来对浅拷贝进行改写:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">myDeepClone</span>(<span class=\"params\">target</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (<span class=\"keyword\">typeof</span> target === <span class=\"string\">'object'</span>) {</span><br><span class=\"line\"> <span class=\"keyword\">let</span> cloneTarget = {};</span><br><span class=\"line\"> <span class=\"keyword\">for</span> (<span class=\"keyword\">const</span> key <span class=\"keyword\">in</span> target) {</span><br><span class=\"line\"> cloneTarget[key] = myDeepClone(target[key]);</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> cloneTarget</span><br><span class=\"line\"> } <span class=\"keyword\">else</span> {</span><br><span class=\"line\"> <span class=\"keyword\">return</span> target;</span><br><span class=\"line\"> }</span><br><span class=\"line\"></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"comment\">// test</span></span><br><span class=\"line\"><span class=\"keyword\">let</span> obj1 = {</span><br><span class=\"line\"> person: {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span></span><br><span class=\"line\"> },</span><br><span class=\"line\"> age: <span class=\"number\">23</span></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">let</span> obj2 = myDeepClone(obj1);</span><br><span class=\"line\">obj2.person.name = <span class=\"string\">'Tom'</span>;</span><br><span class=\"line\">obj2.age = <span class=\"string\">'123'</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj1) <span class=\"comment\">// {person: {name: "CalDey"}, age: "23"}</span></span><br></pre></td></tr></table></figure></div>\n\n<blockquote>\n<p>注意:这是一个最基础的深拷贝,因此它非常的简陋,比如没有考虑target中有数组的情况:</p>\n</blockquote>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// test</span></span><br><span class=\"line\"><span class=\"keyword\">let</span> obj = {</span><br><span class=\"line\"> arr: [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>]</span><br><span class=\"line\">};</span><br><span class=\"line\"><span class=\"comment\">// []被转化成了{}</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(myDeepClone(obj)); <span class=\"comment\">// { arr: {1,2,3} }</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"4-3-改进myDeepClone\"><a href=\"#4-3-改进myDeepClone\" class=\"headerlink\" title=\"4.3.改进myDeepClone()\"></a>4.3.改进myDeepClone()</h2><p>改进数组:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">myDeepClone</span>(<span class=\"params\">target</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (<span class=\"keyword\">typeof</span> target === <span class=\"string\">'object'</span>) {</span><br><span class=\"line\"> <span class=\"comment\">// 三元表达式判断数据类型</span></span><br><span class=\"line\"> <span class=\"keyword\">let</span> cloneTarget = <span class=\"built_in\">Array</span>.isArray(target) ? [] : {};</span><br><span class=\"line\"> <span class=\"keyword\">for</span> (<span class=\"keyword\">const</span> key <span class=\"keyword\">in</span> target) {</span><br><span class=\"line\"> cloneTarget[key] = myDeepClone(target[key]);</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> cloneTarget</span><br><span class=\"line\"> } <span class=\"keyword\">else</span> {</span><br><span class=\"line\"> <span class=\"keyword\">return</span> target;</span><br><span class=\"line\"> }</span><br><span class=\"line\"></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"comment\">// test</span></span><br><span class=\"line\"><span class=\"keyword\">let</span> obj = {</span><br><span class=\"line\"> arr: [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>]</span><br><span class=\"line\">};</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(myDeepClone(obj)); <span class=\"comment\">// { arr: [1,2,3] }</span></span><br></pre></td></tr></table></figure></div>\n\n<p>对象的属性如果直接或者间接引用了自身会发生循环引用:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// test</span></span><br><span class=\"line\"><span class=\"keyword\">let</span> obj = {};</span><br><span class=\"line\">obj.obj = obj;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(myDeepClone(obj)); <span class=\"comment\">// Maximum call stack size exceeded</span></span><br><span class=\"line\"><span class=\"comment\">// 由于循环引用递归陷入死循环导致栈内存溢出</span></span><br></pre></td></tr></table></figure></div>\n\n<p>为了解决循环引用问题,我们开辟一个新空间,来存储对象和拷贝对象的对应关系,当我们拷贝对象之前,先判断是否拷贝过,有的话直接返回,如果没有再继续拷贝。</p>\n<p>我们选用Map以键值对形式存储数据:</p>\n<ul>\n<li>检查Map中是否有克隆过的对象</li>\n<li>有,直接返回</li>\n<li>没有,以键值对形式存储</li>\n<li>继续克隆</li>\n</ul>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">myDeepClone</span>(<span class=\"params\">target, map = <span class=\"keyword\">new</span> <span class=\"built_in\">Map</span>()</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (<span class=\"keyword\">typeof</span> target === <span class=\"string\">'object'</span>) {</span><br><span class=\"line\"> <span class=\"keyword\">let</span> cloneTarget = <span class=\"built_in\">Array</span>.isArray(target) ? [] : {};</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (map.get(target)) {</span><br><span class=\"line\"> <span class=\"keyword\">return</span> map.get(target);</span><br><span class=\"line\"> }</span><br><span class=\"line\"> map.set(target, cloneTarget);</span><br><span class=\"line\"> <span class=\"keyword\">for</span> (<span class=\"keyword\">const</span> key <span class=\"keyword\">in</span> target) {</span><br><span class=\"line\"> cloneTarget[key] = myDeepClone(target[key], map);</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> cloneTarget</span><br><span class=\"line\"> } <span class=\"keyword\">else</span> {</span><br><span class=\"line\"> <span class=\"keyword\">return</span> target;</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"comment\">// test</span></span><br><span class=\"line\"><span class=\"keyword\">let</span> obj = {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span></span><br><span class=\"line\">};</span><br><span class=\"line\">obj.obj = obj;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(clone(obj)); <span class=\"comment\">// Circular</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<blockquote>\n<p>内容参考自:<br><a href=\"https://juejin.cn/book/6844733763675488269/section/6844733763759374350\">前端面试之道</a><br><a href=\"https://github.com/ljianshu/Blog/issues/5\">浅拷贝与深拷贝</a><br><a href=\"https://segmentfault.com/a/1190000020255831\">如何写出一个惊艳面试官的深拷贝?</a></p>\n</blockquote>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaSciprt-立即执行函数","url":"/2021/02/20/JavaScript-%E7%AB%8B%E5%8D%B3%E6%89%A7%E8%A1%8C%E5%87%BD%E6%95%B0/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-什么是立即执行函数?\"><a href=\"#1-什么是立即执行函数?\" class=\"headerlink\" title=\"1.什么是立即执行函数?\"></a>1.什么是立即执行函数?</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">add(<span class=\"number\">1</span>, <span class=\"number\">2</span>);</span><br><span class=\"line\">add(<span class=\"number\">4</span>, <span class=\"number\">5</span>);</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">add</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a + b)</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>普通函数通过手动调用执行,执行完毕后不会释放,可以重复调用</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">var</span> a = <span class=\"number\">1</span>,</span><br><span class=\"line\"> b = <span class=\"number\">2</span>;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a + b)</span><br><span class=\"line\">})();</span><br><span class=\"line\">test(); <span class=\"comment\">// test is not defined</span></span><br></pre></td></tr></table></figure></div>\n\n<p>立即执行函数自动执行,执行完毕后立即释放,不能再次调用</p>\n<p>立即执行函数也可以像普通函数一样传参和获取返回值</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 传参</span></span><br><span class=\"line\">(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a + b)</span><br><span class=\"line\">})(<span class=\"number\">1</span>, <span class=\"number\">2</span>);</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 通过全局变量接受,获取返回值</span></span><br><span class=\"line\"><span class=\"keyword\">var</span> num = (<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> a + b;</span><br><span class=\"line\">})(<span class=\"number\">2</span>, <span class=\"number\">4</span>);</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(num);</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"2-函数表达式\"><a href=\"#2-函数表达式\" class=\"headerlink\" title=\"2.函数表达式\"></a>2.函数表达式</h1><p>只有函数表达式可以被执行符号()执行</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\"></span>)</span>{}(); <span class=\"comment\">// 不可执行</span></span><br><span class=\"line\"><span class=\"keyword\">var</span> test = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{} (); <span class=\"comment\">// 可执行</span></span><br><span class=\"line\">(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\"></span>) </span>{})(); <span class=\"comment\">// 可执行</span></span><br><span class=\"line\">(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\"></span>)</span>{}()); <span class=\"comment\">// 可执行</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> test = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">1</span>);</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(test); <span class=\"comment\">// function() {}</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> test = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">1</span>);</span><br><span class=\"line\">}();</span><br><span class=\"line\"><span class=\"comment\">// 函数执行完成后销毁</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(test); <span class=\"comment\">// undefined</span></span><br></pre></td></tr></table></figure></div>\n\n<p>可以通过隐式转换将函数声明转化为函数表达式( + - * / && || …)</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">+ <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">1</span>)</span><br><span class=\"line\">}();</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"3-使用场景\"><a href=\"#3-使用场景\" class=\"headerlink\" title=\"3.使用场景\"></a>3.使用场景</h1><p>通过立即执行函数打印0-9</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">for</span> (<span class=\"keyword\">var</span> i = <span class=\"number\">0</span>; i < <span class=\"number\">10</span>; i++) {</span><br><span class=\"line\"> (<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">document</span>.write(i + <span class=\"string\">' '</span>);</span><br><span class=\"line\"> })(i);</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\">test();</span><br></pre></td></tr></table></figure></div>\n\n<p>setTimeout</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> i;</span><br><span class=\"line\"><span class=\"keyword\">for</span>(i = <span class=\"number\">1</span>; i <= <span class=\"number\">3</span>; i++) {</span><br><span class=\"line\"> (<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">j</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">setTimeout</span>(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(j)</span><br><span class=\"line\"> }, <span class=\"number\">0</span>)</span><br><span class=\"line\"> })(i);</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>封装简易插件</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 封装简易计算器</span></span><br><span class=\"line\"><span class=\"keyword\">var</span> modules = (<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">plus</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> a + b;</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">minus</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> a - b;</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">mul</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> a * b;</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">div</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> a / b;</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> {</span><br><span class=\"line\"> plus,</span><br><span class=\"line\"> minus,</span><br><span class=\"line\"> mul,</span><br><span class=\"line\"> div</span><br><span class=\"line\"> }</span><br><span class=\"line\">})()</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(modules.plus(<span class=\"number\">5</span>,<span class=\"number\">8</span>));</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(modules.minus(<span class=\"number\">5</span>,<span class=\"number\">8</span>));</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(modules.mul(<span class=\"number\">5</span>,<span class=\"number\">8</span>));</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(modules.div(<span class=\"number\">5</span>,<span class=\"number\">8</span>));</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-类数组","url":"/2021/02/02/JavaScript-%E7%B1%BB%E6%95%B0%E7%BB%84/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-什么是类数组?\"><a href=\"#1-什么是类数组?\" class=\"headerlink\" title=\"1.什么是类数组?\"></a>1.什么是类数组?</h1><p>JavaScript中常见的类数组有arguments对象和DOM方法的返回结果:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\"></span>)</span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">arguments</span>)</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">arguments</span> <span class=\"keyword\">instanceof</span> <span class=\"built_in\">Array</span>) <span class=\"comment\">// false</span></span><br><span class=\"line\"> <span class=\"comment\">// arguments.push(123)</span></span><br><span class=\"line\">}</span><br><span class=\"line\">test(<span class=\"string\">'CalDey'</span>, <span class=\"number\">23</span>, <span class=\"string\">'hello'</span>)</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> divs = <span class=\"built_in\">document</span>.getElementsByTagName(<span class=\"string\">'div'</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(divs) <span class=\"comment\">// HTMLCollection</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(divs <span class=\"keyword\">instanceof</span> <span class=\"built_in\">Array</span>) <span class=\"comment\">// false</span></span><br><span class=\"line\"><span class=\"comment\">// divs.push(123) // 报错</span></span><br></pre></td></tr></table></figure></div>\n\n<p>类数组的特征主要有两个:</p>\n<ul>\n<li>拥有length属性</li>\n<li>不具有数组所具有的方法</li>\n</ul>\n<hr>\n<h1 id=\"2-类数组如何转化成数组\"><a href=\"#2-类数组如何转化成数组\" class=\"headerlink\" title=\"2.类数组如何转化成数组\"></a>2.类数组如何转化成数组</h1><h2 id=\"2-1-遍历类数组,将元素放入新数组\"><a href=\"#2-1-遍历类数组,将元素放入新数组\" class=\"headerlink\" title=\"2.1.遍历类数组,将元素放入新数组\"></a>2.1.遍历类数组,将元素放入新数组</h2><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> divs = <span class=\"built_in\">document</span>.getElementsByTagName(<span class=\"string\">'div'</span>)</span><br><span class=\"line\"><span class=\"keyword\">let</span> arr = []</span><br><span class=\"line\"><span class=\"keyword\">for</span>(<span class=\"keyword\">let</span> i <span class=\"keyword\">in</span> divs){</span><br><span class=\"line\"> arr.push(divs[i])</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr <span class=\"keyword\">instanceof</span> <span class=\"built_in\">Array</span>) <span class=\"comment\">// true</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"2-2-Array-prototype-slice-call-arguments\"><a href=\"#2-2-Array-prototype-slice-call-arguments\" class=\"headerlink\" title=\"2.2.Array.prototype.slice.call(arguments)\"></a>2.2.Array.prototype.slice.call(arguments)</h2><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\"></span>)</span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">arguments</span>)</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">arguments</span> <span class=\"keyword\">instanceof</span> <span class=\"built_in\">Array</span>) <span class=\"comment\">// false</span></span><br><span class=\"line\"> <span class=\"keyword\">let</span> arr = <span class=\"built_in\">Array</span>.prototype.slice.call(<span class=\"built_in\">arguments</span>)</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(arr)</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(arr <span class=\"keyword\">instanceof</span> <span class=\"built_in\">Array</span>) <span class=\"comment\">// true</span></span><br><span class=\"line\">}</span><br><span class=\"line\">test(<span class=\"string\">'CalDey'</span>, <span class=\"number\">23</span>, <span class=\"string\">'hello'</span>)</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"2-3-apply\"><a href=\"#2-3-apply\" class=\"headerlink\" title=\"2.3.apply\"></a>2.3.apply</h2><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> arrayLike = {</span><br><span class=\"line\"> <span class=\"number\">0</span>: <span class=\"string\">'es6'</span>,</span><br><span class=\"line\"> <span class=\"number\">1</span>: <span class=\"string\">'es7'</span>,</span><br><span class=\"line\"> <span class=\"number\">2</span>: <span class=\"string\">'es8'</span>,</span><br><span class=\"line\"> length: <span class=\"number\">3</span></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">let</span> arr = [].concat.apply([], arrayLike)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr <span class=\"keyword\">instanceof</span> <span class=\"built_in\">Array</span>) <span class=\"comment\">// true</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"2-4-es6-扩展运算符\"><a href=\"#2-4-es6-扩展运算符\" class=\"headerlink\" title=\"2.4.es6-扩展运算符\"></a>2.4.es6-扩展运算符</h2><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> divs = <span class=\"built_in\">document</span>.getElementsByTagName(<span class=\"string\">'div'</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(divs)</span><br><span class=\"line\"><span class=\"keyword\">let</span> arr = [...divs]</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr <span class=\"keyword\">instanceof</span> <span class=\"built_in\">Array</span>) <span class=\"comment\">// true</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"2-5-es6-Array-from\"><a href=\"#2-5-es6-Array-from\" class=\"headerlink\" title=\"2.5.es6-Array.from\"></a>2.5.es6-Array.from</h2><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> divs = <span class=\"built_in\">document</span>.getElementsByTagName(<span class=\"string\">'div'</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(divs)</span><br><span class=\"line\"><span class=\"keyword\">let</span> arr = <span class=\"built_in\">Array</span>.from(divs)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr <span class=\"keyword\">instanceof</span> <span class=\"built_in\">Array</span>) <span class=\"comment\">// true</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-轻松弄懂this指向","url":"/2020/12/13/JavaScript-%E8%BD%BB%E6%9D%BE%E5%BC%84%E6%87%82this%E6%8C%87%E5%90%91/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<p>this取值是在函数执行时确定的,不是在函数定义时确定的</p>\n<h1 id=\"1-常见使用场景\"><a href=\"#1-常见使用场景\" class=\"headerlink\" title=\"1.常见使用场景\"></a>1.常见使用场景</h1><p>想要弄清楚this的指向,首先我们需要先了解this的几种常见使用场景:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">foo</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.a)</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">var</span> a = <span class=\"number\">1</span></span><br><span class=\"line\">foo() <span class=\"comment\">// 直接调用(全局调用)</span></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> obj = {</span><br><span class=\"line\"> a: <span class=\"number\">2</span>,</span><br><span class=\"line\"> foo: foo</span><br><span class=\"line\">}</span><br><span class=\"line\">obj.foo() <span class=\"comment\">// XX对象的方法</span></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> c = <span class=\"keyword\">new</span> foo() <span class=\"comment\">// 构造函数 </span></span><br></pre></td></tr></table></figure></div>\n\n<p>上面这段代码涉及了this的3个常见使用场景,这三种场景this的指向在绝大部分情况下是固定的,我们记住即可:</p>\n<ul>\n<li>直接调用:直接调用时,函数(本文中指foo函数)无论被放在任何地方,this一定指向window</li>\n<li>对象的方法:谁调用了函数,this就指向谁 </li>\n<li>构造函数: 对于构造函数来说,this被绑定在实例对象上,任何方式都不能改变</li>\n</ul>\n<hr>\n<p>对于大部分代码来说,this的指向无外乎以上三种情况,下面来介绍this特殊的使用场景:</p>\n<h1 id=\"2-箭头函数\"><a href=\"#2-箭头函数\" class=\"headerlink\" title=\"2.箭头函数\"></a>2.箭头函数</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">a</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\">a()()() <span class=\"comment\">// window</span></span><br></pre></td></tr></table></figure></div>\n\n<p>上面这段代码看似复杂,其实很简单,首先箭头函数中是不绑定this的,箭头函数中的this只取决于<font color=#ff503e><strong>箭头函数外层的第一个非箭头函数的作用域</strong></font>中的this。这个示例中,最外层是a,this指向window,<font color=#ff503e><strong>另外注意对箭头函数使用bind这类函数是无效的:</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> name = <span class=\"string\">'window'</span></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">let</span> fn = <span class=\"function\">() =></span> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name)</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">var</span> person = {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span></span><br><span class=\"line\">}</span><br><span class=\"line\">fn() <span class=\"comment\">// window</span></span><br><span class=\"line\">fn.bind(person) <span class=\"comment\">// window</span></span><br></pre></td></tr></table></figure></div>\n\n<p>异步this指向window,可以通过箭头函数解决异步指向问题</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> person = {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span>,</span><br><span class=\"line\"> <span class=\"function\"><span class=\"title\">sayHi</span>(<span class=\"params\"></span>)</span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>)</span><br><span class=\"line\"> },</span><br><span class=\"line\"> <span class=\"function\"><span class=\"title\">wait</span>(<span class=\"params\"></span>)</span> {</span><br><span class=\"line\"> <span class=\"comment\">// 异步</span></span><br><span class=\"line\"> <span class=\"built_in\">setTimeout</span>(<span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>)</span><br><span class=\"line\"> })</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\">person.sayHi(); <span class=\"comment\">// 当前对象</span></span><br><span class=\"line\">person.wait(); <span class=\"comment\">// window</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> person = {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span>,</span><br><span class=\"line\"> <span class=\"function\"><span class=\"title\">sayHi</span>(<span class=\"params\"></span>)</span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>)</span><br><span class=\"line\"> },</span><br><span class=\"line\"> <span class=\"function\"><span class=\"title\">wait</span>(<span class=\"params\"></span>)</span> {</span><br><span class=\"line\"> <span class=\"built_in\">setTimeout</span>(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>)</span><br><span class=\"line\"> })</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\">person.sayHi(); <span class=\"comment\">// 当前对象</span></span><br><span class=\"line\">person.wait(); <span class=\"comment\">// 当前对象</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"3-call-bind-apply\"><a href=\"#3-call-bind-apply\" class=\"headerlink\" title=\"3.call,bind,apply\"></a>3.call,bind,apply</h1><p>this取决第一个参数,如果第一个参数为空,那么就是window。<font color=#ff503e><strong>如果同时调用多个bind,this指向永远由第一个bind决定:</strong></font></p>\n<iframe width=\"100%\" height=\"400\" src=\"//jsrun.net/8kaKp/embedded/js/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h1 id=\"4-嵌套函数\"><a href=\"#4-嵌套函数\" class=\"headerlink\" title=\"4.嵌套函数\"></a>4.嵌套函数</h1><p>上文中提到过,对于对象的方法来说,谁调用this就指向谁,这个结论在大多数情况中都适用。不过也有例外,比如嵌套函数:在非严格模式的js语法中,如果一个对象内存在方法,则该方法的this指向当前对象。<font color=#ff503e><strong>若方法中再次包含函数方法,则该嵌套函数指向全局,this指向window。</strong></font></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">name = <span class=\"string\">"window"</span>;</span><br><span class=\"line\"><span class=\"keyword\">var</span> obj = {</span><br><span class=\"line\"> name: <span class=\"string\">"obj"</span>,</span><br><span class=\"line\"> func: <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>)</span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name)</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{ </span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\">obj.func()() <span class=\"comment\">// obj->window</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"5-简易流程图\"><a href=\"#5-简易流程图\" class=\"headerlink\" title=\"5.简易流程图\"></a>5.简易流程图</h1><p>以上就是this指向在不同场景下遵循的基本规则,事实上常常会出现多个规则同时存在的情况,这就需要我们根据不同规则之间的优先级顺序来判断this指向了:</p>\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/this%E6%8C%87%E5%90%91%E6%B5%81%E7%A8%8B%E5%9B%BE.PNG\" alt=\"this指向流程图\"></p>\n<hr>\n<h1 id=\"6-一些面试题\"><a href=\"#6-一些面试题\" class=\"headerlink\" title=\"6.一些面试题\"></a>6.一些面试题</h1><p>下面我们通过几道面试题来加深对this指向的理解</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 第一题</span></span><br><span class=\"line\"><span class=\"keyword\">var</span> name = <span class=\"string\">'window'</span></span><br><span class=\"line\"><span class=\"keyword\">var</span> person1 = {</span><br><span class=\"line\"> name: <span class=\"string\">'person1'</span>,</span><br><span class=\"line\"> foo1: <span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name)</span><br><span class=\"line\"> },</span><br><span class=\"line\"> foo2: <span class=\"function\">() =></span> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name),</span><br><span class=\"line\"> foo3: <span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> },</span><br><span class=\"line\"> foo4: <span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> },</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">var</span> person2 = { <span class=\"attr\">name</span>: <span class=\"string\">'person2'</span> }</span><br><span class=\"line\">person1.foo1()</span><br><span class=\"line\">person1.foo1.call(person2)</span><br><span class=\"line\">person1.foo2()</span><br><span class=\"line\">person1.foo2.call(person2)</span><br><span class=\"line\">person1.foo3()()</span><br><span class=\"line\">person1.foo3.call(person2)()</span><br><span class=\"line\">person1.foo3().call(person2)</span><br><span class=\"line\">person1.foo4()()</span><br><span class=\"line\">person1.foo4.call(person2)()</span><br><span class=\"line\">person1.foo4().call(person2)</span><br></pre></td></tr></table></figure></div>\n\n<details>\n <summary>点我查看答案</summary>\n <div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// this指向调用对象person1</span></span><br><span class=\"line\">person1.foo1() <span class=\"comment\">// person1</span></span><br><span class=\"line\"><span class=\"comment\">// call参数为person2,this绑定person2</span></span><br><span class=\"line\">person1.foo1.call(person2) <span class=\"comment\">// person2</span></span><br><span class=\"line\"><span class=\"comment\">// foo2是箭头函数,this指向箭头函数外部第一个普通函数,指向window</span></span><br><span class=\"line\">person1.foo2() <span class=\"comment\">// window</span></span><br><span class=\"line\"><span class=\"comment\">// foo2为箭头函数,call对箭头函数无效</span></span><br><span class=\"line\">person1.foo2.call(person2) <span class=\"comment\">// window</span></span><br><span class=\"line\"><span class=\"comment\">// foo3为嵌套函数,指向window</span></span><br><span class=\"line\">person1.foo3()() <span class=\"comment\">// window</span></span><br><span class=\"line\"><span class=\"comment\">// foo3为嵌套函数绑定person2,内部函数call参数为空,仍然指向window</span></span><br><span class=\"line\">person1.foo3.call(person2)() <span class=\"comment\">// window</span></span><br><span class=\"line\"><span class=\"comment\">// 内部函数call参数为person2,绑定person2</span></span><br><span class=\"line\">person1.foo3().call(person2) <span class=\"comment\">// person2</span></span><br><span class=\"line\"><span class=\"comment\">// foo4返回一个箭头函数,this指向箭头函数外部第一个普通函数,指向person1</span></span><br><span class=\"line\">person1.foo4()() <span class=\"comment\">// person1</span></span><br><span class=\"line\"><span class=\"comment\">// foo4绑定person2,返回一个箭头函数,箭头函数指向person2</span></span><br><span class=\"line\">person1.foo4.call(person2)() <span class=\"comment\">// person2</span></span><br><span class=\"line\"><span class=\"comment\">// foo4返回箭头函数,call对箭头函数无效</span></span><br><span class=\"line\">person1.foo4().call(person2) <span class=\"comment\">// person1</span></span><br></pre></td></tr></table></figure></div>\n</details>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 第二题</span></span><br><span class=\"line\"><span class=\"keyword\">var</span> name = <span class=\"string\">'window'</span></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Person</span>(<span class=\"params\">name</span>) </span>{ </span><br><span class=\"line\"> <span class=\"built_in\">this</span>.name = name </span><br><span class=\"line\"> <span class=\"built_in\">this</span>.foo1 = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{ </span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name) </span><br><span class=\"line\"> }, </span><br><span class=\"line\"> <span class=\"built_in\">this</span>.foo2 = <span class=\"function\">() =></span> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name), </span><br><span class=\"line\"> <span class=\"built_in\">this</span>.foo3 = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{ </span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{ </span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name) </span><br><span class=\"line\"> } </span><br><span class=\"line\"> }, </span><br><span class=\"line\"> <span class=\"built_in\">this</span>.foo4 = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{ </span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\">() =></span> { </span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name) </span><br><span class=\"line\"> } </span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">var</span> person1 = <span class=\"keyword\">new</span> Person(<span class=\"string\">'person1'</span>)</span><br><span class=\"line\"><span class=\"keyword\">var</span> person2 = <span class=\"keyword\">new</span> Person(<span class=\"string\">'person2'</span>)</span><br><span class=\"line\">person1.foo1()</span><br><span class=\"line\">person1.foo1.call(person2)</span><br><span class=\"line\">person1.foo2()</span><br><span class=\"line\">person1.foo2.call(person2)</span><br><span class=\"line\">person1.foo3()()</span><br><span class=\"line\">person1.foo3.call(person2)()</span><br><span class=\"line\">person1.foo3().call(person2)</span><br><span class=\"line\">person1.foo4()()</span><br><span class=\"line\">person1.foo4.call(person2)()</span><br><span class=\"line\">person1.foo4().call(person2)</span><br></pre></td></tr></table></figure></div>\n\n<details>\n <summary>点我查看答案</summary>\n <div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">person1.foo1() <span class=\"comment\">// person1</span></span><br><span class=\"line\">person1.foo1.call(person2) <span class=\"comment\">// person2</span></span><br><span class=\"line\">person1.foo2() <span class=\"comment\">// person1</span></span><br><span class=\"line\">person1.foo2.call(person2) <span class=\"comment\">// person1</span></span><br><span class=\"line\">person1.foo3()() <span class=\"comment\">// window</span></span><br><span class=\"line\">person1.foo3.call(person2)() <span class=\"comment\">// window</span></span><br><span class=\"line\">person1.foo3().call(person2) <span class=\"comment\">// person2</span></span><br><span class=\"line\">person1.foo4()() <span class=\"comment\">// person1</span></span><br><span class=\"line\">person1.foo4.call(person2)() <span class=\"comment\">// person2</span></span><br><span class=\"line\">person1.foo4().call(person2) <span class=\"comment\">// person1</span></span><br></pre></td></tr></table></figure></div>\n</details>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 第三题</span></span><br><span class=\"line\"><span class=\"keyword\">var</span> name = <span class=\"string\">'window'</span></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Person</span>(<span class=\"params\">name</span>) </span>{ </span><br><span class=\"line\"> <span class=\"built_in\">this</span>.name = name</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.obj = { </span><br><span class=\"line\"> name: <span class=\"string\">'obj'</span>,</span><br><span class=\"line\"> foo1: <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{ </span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{ </span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name) </span><br><span class=\"line\"> } </span><br><span class=\"line\"> },</span><br><span class=\"line\"> foo2: <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{ </span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\">() =></span> { </span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name) </span><br><span class=\"line\"> } </span><br><span class=\"line\"> } </span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">var</span> person1 = <span class=\"keyword\">new</span> Person(<span class=\"string\">'person1'</span>)</span><br><span class=\"line\"><span class=\"keyword\">var</span> person2 = <span class=\"keyword\">new</span> Person(<span class=\"string\">'person2'</span>)</span><br><span class=\"line\">person1.obj.foo1()()</span><br><span class=\"line\">person1.obj.foo1.call(person2)()</span><br><span class=\"line\">person1.obj.foo1().call(person2)</span><br><span class=\"line\">person1.obj.foo2()()</span><br><span class=\"line\">person1.obj.foo2.call(person2)()</span><br><span class=\"line\">person1.obj.foo2().call(person2)</span><br></pre></td></tr></table></figure></div>\n\n<details>\n <summary>点我查看答案</summary>\n <div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">person1.obj.foo1()() <span class=\"comment\">// window</span></span><br><span class=\"line\">person1.obj.foo1.call(person2)() <span class=\"comment\">// window</span></span><br><span class=\"line\">person1.obj.foo1().call(person2) <span class=\"comment\">// person2</span></span><br><span class=\"line\">person1.obj.foo2()() <span class=\"comment\">// obj</span></span><br><span class=\"line\">person1.obj.foo2.call(person2)() <span class=\"comment\">// person2</span></span><br><span class=\"line\">person1.obj.foo2().call(person2) <span class=\"comment\">// obj</span></span><br></pre></td></tr></table></figure></div>\n</details>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 第四题</span></span><br><span class=\"line\">name = <span class=\"string\">"window"</span>;</span><br><span class=\"line\"><span class=\"keyword\">var</span> obj = {</span><br><span class=\"line\"> name: <span class=\"string\">"obj"</span>,</span><br><span class=\"line\"> func0: <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name);</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\">() =></span> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name);</span><br><span class=\"line\"> },</span><br><span class=\"line\"> func1: <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name);</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{ <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name); };</span><br><span class=\"line\"> },</span><br><span class=\"line\"> func2: <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name);</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{ <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name); };</span><br><span class=\"line\"> },</span><br><span class=\"line\"> func3: <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name);</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\">() =></span> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">this</span>.name);</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">var</span> env = {</span><br><span class=\"line\"> name: <span class=\"string\">"env"</span>,</span><br><span class=\"line\"> func0: obj.func0(),</span><br><span class=\"line\"> func1: obj.func1(),</span><br><span class=\"line\"> func2: obj.func2(),</span><br><span class=\"line\"> func3: obj.func3()</span><br><span class=\"line\">}</span><br><span class=\"line\">env.func0();</span><br><span class=\"line\">env.func1();</span><br><span class=\"line\">env.func2();</span><br><span class=\"line\">env.func3();</span><br></pre></td></tr></table></figure></div>\n\n<details>\n <summary>点我查看答案</summary>\n <div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// console.log(obj.func0) // () => { console.log(this.name); return () => console.log(this.name); } </span></span><br><span class=\"line\"><span class=\"comment\">// console.log(env.func0) // () => console.log(this.name)</span></span><br><span class=\"line\">func0: obj.func0(), <span class=\"comment\">// window</span></span><br><span class=\"line\">func1: obj.func1(), <span class=\"comment\">// obj</span></span><br><span class=\"line\">func2: obj.func2(), <span class=\"comment\">// window</span></span><br><span class=\"line\">func3: obj.func3() <span class=\"comment\">// obj</span></span><br><span class=\"line\">env.func0(); <span class=\"comment\">// window</span></span><br><span class=\"line\">env.func1(); <span class=\"comment\">// env</span></span><br><span class=\"line\">env.func2(); <span class=\"comment\">// env</span></span><br><span class=\"line\">env.func3(); <span class=\"comment\">// obj</span></span><br></pre></td></tr></table></figure></div>\n</details>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 第五题</span></span><br><span class=\"line\"><span class=\"keyword\">var</span> name = <span class=\"string\">"Window"</span>;</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">var</span> object = {</span><br><span class=\"line\"> name : <span class=\"string\">"My Object"</span>,</span><br><span class=\"line\"></span><br><span class=\"line\"> getNameFunc : <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>)</span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>)</span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"built_in\">this</span>.name;</span><br><span class=\"line\"> };</span><br><span class=\"line\"> }</span><br><span class=\"line\"> };</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(object.getNameFunc()()); <span class=\"comment\">// Window</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 第六题</span></span><br><span class=\"line\"> <span class=\"keyword\">var</span> name = <span class=\"string\">"Window"</span>;</span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"keyword\">var</span> object = {</span><br><span class=\"line\"> name : <span class=\"string\">"My Object"</span>,</span><br><span class=\"line\"></span><br><span class=\"line\"> getNameFunc : <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>)</span>{</span><br><span class=\"line\"> <span class=\"keyword\">var</span> that = <span class=\"built_in\">this</span>;</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>)</span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> that.name;</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><span class=\"line\"></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(object.getNameFunc()()); <span class=\"comment\">// My Object</span></span><br></pre></td></tr></table></figure></div>\n\n<blockquote>\n<p>this对象是动态的,随时会改变,而var that = this之后,that不会改变,仍然指向之前的this,这样就不会找不到原来的对象</p>\n</blockquote>\n<hr>\n<p>7.补充</p>\n<p>事件处理函数内部的this总是指向被绑定DOM元素</p>\n<blockquote>\n<p>内容参考自:<br><a href=\"https://www.jianshu.com/p/b1e0eb9151f9\">JavaScript之彻底搞懂this的指向</a><br><a href=\"http://caibaojian.com/interview-map/frontend/#this\">前端面试之道</a></p>\n</blockquote>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-轻松理解原型和原型链","url":"/2020/12/16/JavaScript-%E8%BD%BB%E6%9D%BE%E7%90%86%E8%A7%A3%E5%8E%9F%E5%9E%8B%E5%92%8C%E5%8E%9F%E5%9E%8B%E9%93%BE/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-一个简单示例\"><a href=\"#1-一个简单示例\" class=\"headerlink\" title=\"1.一个简单示例\"></a>1.一个简单示例</h1><p>我们首先来看一个简单的例子:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> obj = {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span></span><br><span class=\"line\">};</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"keyword\">typeof</span> obj); <span class=\"comment\">// object</span></span><br><span class=\"line\">obj = obj.toString();</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"keyword\">typeof</span> obj); <span class=\"comment\">// string</span></span><br></pre></td></tr></table></figure></div>\n\n<p>这段简单的代码创建了一个对象obj,并且把对象转换成了字符串类型。需要注意的是,我们并没有给obj定义toString方法,为了解决这个疑问,我们先看一下obj里都有什么:</p>\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/202012161555.PNG\"></p>\n<p>我们惊讶的发现,obj上居然有一个__proto__属性,那么问题只能出在这个属性身上了,我们来看看__proto__究竟是什么:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"keyword\">typeof</span> obj.__proto__) <span class=\"comment\">// object</span></span><br></pre></td></tr></table></figure></div>\n\n<p>我们对__proto__使用typeof,发现是一个对象。其实每个对象都有__proto__属性,这个属性指向原型。</p>\n<p>看一眼__proto__里具体有哪些东西:</p>\n<p>我们发现了constructor属性,也就是构造函数</p>\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/202012161622.PNG\"></p>\n<p>constructor属性中有一个prototype属性,有趣的是,其值与__proto__完全一致:</p>\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/202012161633.PNG\"></p>\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/202012161645.PNG\"></p>\n<p>通过上面的例子,我们对__proto__,prototype和constructor已经有了基本的了解,下面我们就可以来详细介绍这些属性具体都是做什么的。</p>\n<hr>\n<h1 id=\"2-原型和原型链\"><a href=\"#2-原型和原型链\" class=\"headerlink\" title=\"2.原型和原型链\"></a>2.原型和原型链</h1><h2 id=\"2-1-prototype\"><a href=\"#2-1-prototype\" class=\"headerlink\" title=\"2.1.prototype\"></a>2.1.prototype</h2><p>prototype是一个显式原型属性,每一个函数都有prototype属性,指向一个对象。基本所有函数都有这个属性,当然有一个例外,Function.prototype.bind()没有这个属性。</p>\n<p>当我们声明一个函数时,会自动创建一个prototype属性:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Fn</span>(<span class=\"params\"></span>) </span>{}</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(Fn.prototype)</span><br></pre></td></tr></table></figure></div>\n\n<p>这个属性的值是一个对象,即原型,其只有一个属性constructor,constructor对应构造函数,也就是Fn。</p>\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/202012161714.PNG\"></p>\n<p>对于普通函数来说,prototype属性基本没用,但对于构造函数来说,生成实例时,该属性会自动成为实例的原型。也就是说,如果属性和方法定义在原型上,那么所有实例对象都能共享该属性和方法:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Person</span>(<span class=\"params\">age</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.age = age;</span><br><span class=\"line\">}</span><br><span class=\"line\">Person.prototype.name = <span class=\"string\">'CalDey'</span>;</span><br><span class=\"line\"><span class=\"keyword\">var</span> person1 = <span class=\"keyword\">new</span> Person();</span><br><span class=\"line\"><span class=\"keyword\">var</span> person2 = <span class=\"keyword\">new</span> Person();</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(person1.name); <span class=\"comment\">// CalDey</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(person2.name); <span class=\"comment\">// CalDey</span></span><br></pre></td></tr></table></figure></div>\n\n<p>我们用一张图来总结构造函数和实例原型之间的关系:</p>\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvODUwMzc1LzIwMTkwNy84NTAzNzUtMjAxOTA3MDgxNTEwMjQxMzQtNTEyNTU4MDA3LnBuZw.png\"></p>\n<h2 id=\"2-2-proto\"><a href=\"#2-2-proto\" class=\"headerlink\" title=\"2.2.__proto__\"></a>2.2.__proto__</h2><p>__proto__是隐式原型属性,每一个对象都有一个__proto__属性,指向该对象的构造函数的原型,其实指向的是 [[prototype]],但[[prototype]]是内部属性,我们不能访问到,所以通过__proto__来间接访问。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Person</span>(<span class=\"params\"></span>) </span>{}</span><br><span class=\"line\"><span class=\"keyword\">var</span> person = <span class=\"keyword\">new</span> Person;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(person.__proto__ === Person.prototype) <span class=\"comment\">// true</span></span><br></pre></td></tr></table></figure></div>\n\n<p>显然,实例对象的__proto__属性链接到构造函数的原型的过程发生在new过程中,我们花一点时间复习一下new过程:</p>\n<p>new的过程</p>\n<ul>\n<li>1.生成新对象</li>\n<li>2.链接到原型(person.__proto__ = Person.prototype)</li>\n<li>3.绑定this</li>\n<li>4.返回新对象</li>\n</ul>\n<p>现在我们在关系图上补充实例对象和实例原型的关联:</p>\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvODUwMzc1LzIwMTkwNy84NTAzNzUtMjAxOTA3MDgxNTEzMjI1MzAtMTYwODE1Nzk3My5wbmc.png\"></p>\n<h2 id=\"2-3-constructor\"><a href=\"#2-3-constructor\" class=\"headerlink\" title=\"2.3.constructor\"></a>2.3.constructor</h2><p>每个原型(prototype对象)都有一个constructor属性,指向其关联的构造函数:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Person</span>(<span class=\"params\"></span>) </span>{}</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(Person.prototype.constructor === Person) <span class=\"comment\">// true</span></span><br></pre></td></tr></table></figure></div>\n\n<p>constructor属性的作用是,我们可以知道某个实例对象到底是由哪个构造函数产生的:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Person</span>(<span class=\"params\"></span>) </span>{}</span><br><span class=\"line\"><span class=\"keyword\">var</span> person = <span class=\"keyword\">new</span> Person();</span><br><span class=\"line\"></span><br><span class=\"line\">person.constructor === Person <span class=\"comment\">// true</span></span><br><span class=\"line\">person.constructor === Person.prototype.constructor <span class=\"comment\">// true</span></span><br><span class=\"line\">person.hasOwnProperty(<span class=\"string\">'constructor'</span>) <span class=\"comment\">// false</span></span><br></pre></td></tr></table></figure></div>\n\n<p>由于constructor定义在prototype对象上,意味着所有实例对象都可以继承该属性。上面代码中,person是Person的实例对象,但person自身没有constructor属性,该属性继承自Person.protype</p>\n<p>constructor属性表示原型对象和构造函数之间的关联关系,如果修改了原型对象,constructor属性也会发生改变:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Person</span>(<span class=\"params\">name</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.name = name;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(Person.prototype.constructor === Person) <span class=\"comment\">// true</span></span><br><span class=\"line\"></span><br><span class=\"line\">Person.prototype = {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span></span><br><span class=\"line\">};</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(Person.prototype.constructor === Person) <span class=\"comment\">// false</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(Person.prototype.constructor === <span class=\"built_in\">Object</span>) <span class=\"comment\">// Object</span></span><br></pre></td></tr></table></figure></div>\n\n<p>我们将关系图补全:</p>\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvODUwMzc1LzIwMTkwNy84NTAzNzUtMjAxOTA3MDgxNTE2MTU2OTEtMTAxNzYxMTE5MC5wbmc.png\"></p>\n<h2 id=\"2-4-原型链\"><a href=\"#2-4-原型链\" class=\"headerlink\" title=\"2.4.原型链\"></a>2.4.原型链</h2><p>我们创建一个Array对象arr,通过reverse方法将其翻转:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> arr = [<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>];</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.reverse()); <span class=\"comment\">// 3,2,1</span></span><br></pre></td></tr></table></figure></div>\n<p>请注意,我们创建的arr对象本身是不包含reverse方法的,为什么它可以直接使用reverse方法呢?那么该方法只能来自它的原型对象上了,我们通过constructor属性找到arr的原型对象:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(arr.constructor) <span class=\"comment\">// Array</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"built_in\">Array</span>.prototype);</span><br></pre></td></tr></table></figure></div>\n\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/img2.PNG\"></p>\n<p>显然,reverse方法来自arr的原型对象Array.prototype</p>\n<p>当我们访问某个对象的属性或方法时,首先会在当前对象上查找,如果没有找到,就到其原型对象身上查找,如果还是没有找到,会一层层向上查找只到Object.prototype对象,如果仍未找到,那么就会返回null,这个查找过程叫做原型链。</p>\n<p>这张图片生动形象的描述了原型链查找的过程:</p>\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/2019022822050917.jpg\"></p>\n<p>我们对这张图片涉及的几个关键点做一个简短的总结:</p>\n<ul>\n<li>Object是所有对象的父亲,所有对象都可以通过__proto__找到它</li>\n<li>Function是所有函数的父亲,所有函数都可以通过__proto__找到它</li>\n<li>函数的prototype是对象</li>\n<li>每个原型对象都有一个constructor属性,指向其关联构造函数</li>\n<li>对象的__proto__指向原型,__proto__将对象和原型链接起来形成原型链</li>\n<li>原型链的尽头是null</li>\n</ul>\n<hr>\n<h1 id=\"3-typeof和instanceof\"><a href=\"#3-typeof和instanceof\" class=\"headerlink\" title=\"3.typeof和instanceof\"></a>3.typeof和instanceof</h1><h2 id=\"3-1-typeof\"><a href=\"#3-1-typeof\" class=\"headerlink\" title=\"3.1.typeof\"></a>3.1.typeof</h2><p>当我们要判断一个变量的数据类型,大多数情况下都会首选typeof,而令人烦恼的是数组和对象都会返回object,为了解决这个问题,我们可以使用Object.prototype.toString.call(obj)方法,返回[object Type]告诉我们具体的数据类型</p>\n<h2 id=\"3-2-instanceof\"><a href=\"#3-2-instanceof\" class=\"headerlink\" title=\"3.2.instanceof\"></a>3.2.instanceof</h2><p>除了typeof外,我们可以通过instanceof检查构造函数的prototype是否出现在某个实例对象的原型链上:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Father</span>(<span class=\"params\"></span>) </span>{};</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Son</span>(<span class=\"params\"></span>) </span>{};</span><br><span class=\"line\"></span><br><span class=\"line\">Son.prototype = <span class=\"keyword\">new</span> Father();</span><br><span class=\"line\"><span class=\"keyword\">let</span> son = <span class=\"keyword\">new</span> Son();</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(son <span class=\"keyword\">instanceof</span> Son); <span class=\"comment\">// true</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(son <span class=\"keyword\">instanceof</span> Father); <span class=\"comment\">// true</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(son <span class=\"keyword\">instanceof</span> <span class=\"built_in\">Object</span>); <span class=\"comment\">// true</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<blockquote>\n<p>内容参考自:<br><a href=\"https://juejin.cn/book/6844733763675488269/section/6844733763759374350\">前端面试之道</a><br><a href=\"https://github.com/KieSun/Dream/issues/2\">深度解析原型中的各个难点</a><br><a href=\"https://wangdoc.com/javascript/oop/prototype.html\">对象的继承</a><br><a href=\"https://blog.csdn.net/qq_38722097/article/details/88046377\">JS中prototype,[[prototype]]和__proto__的区别和用法</a><br><a href=\"https://wangdoc.com/javascript/oop/prototype.html\">javascript——原型与原型链,constructor</a></p>\n</blockquote>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript-防抖和节流","url":"/2021/02/22/JavaScript-%E9%98%B2%E6%8A%96%E5%92%8C%E8%8A%82%E6%B5%81/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-防抖-debounce\"><a href=\"#1-防抖-debounce\" class=\"headerlink\" title=\"1.防抖(debounce)\"></a>1.防抖(debounce)</h1><p>监听输入框,框内文字变化后触发change事件,如果监听keyup事件,输入过程中会频繁触发change事件</p>\n<p>防抖:用户输入结束或暂停时,才会触发change事件(设置间隔时间)</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><body></span><br><span class=\"line\"> <input type=<span class=\"string\">"text"</span> id=<span class=\"string\">"input"</span>></span><br><span class=\"line\"></body></span><br><span class=\"line\"><script></span><br><span class=\"line\"> <span class=\"keyword\">const</span> input = <span class=\"built_in\">document</span>.getElementById(<span class=\"string\">'input'</span>)</span><br><span class=\"line\"> <span class=\"keyword\">let</span> timer = <span class=\"literal\">null</span></span><br><span class=\"line\"> input.addEventListener(<span class=\"string\">'keyup'</span>, <span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (timer) {</span><br><span class=\"line\"> <span class=\"built_in\">clearTimeout</span>(timer)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> timer = <span class=\"built_in\">setTimeout</span>(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(input.value)</span><br><span class=\"line\"> <span class=\"comment\">// 清空定时器</span></span><br><span class=\"line\"> timer = <span class=\"literal\">null</span></span><br><span class=\"line\"> }, <span class=\"number\">300</span>)</span><br><span class=\"line\"> }, <span class=\"literal\">false</span>)</span><br><span class=\"line\"></script></span><br></pre></td></tr></table></figure></div>\n\n<p>封装debounce函数</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><body></span><br><span class=\"line\"> <input type=<span class=\"string\">"text"</span> id=<span class=\"string\">"input"</span>></span><br><span class=\"line\"></body></span><br><span class=\"line\"><script></span><br><span class=\"line\"> <span class=\"keyword\">const</span> input = <span class=\"built_in\">document</span>.getElementById(<span class=\"string\">'input'</span>)</span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">debounce</span>(<span class=\"params\">fn, delay = <span class=\"number\">500</span></span>) </span>{</span><br><span class=\"line\"> <span class=\"comment\">// timer在闭包中</span></span><br><span class=\"line\"> <span class=\"keyword\">let</span> timer = <span class=\"literal\">null</span></span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (timer) {</span><br><span class=\"line\"> <span class=\"built_in\">clearTimeout</span>(timer)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> timer = <span class=\"built_in\">setTimeout</span>(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> fn.apply(<span class=\"built_in\">this</span>, <span class=\"built_in\">arguments</span>)</span><br><span class=\"line\"> timer = <span class=\"literal\">null</span></span><br><span class=\"line\"> }, delay)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\"></span><br><span class=\"line\"> input.addEventListener(<span class=\"string\">'keyup'</span>, debounce(<span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(input.value)</span><br><span class=\"line\"> }, <span class=\"number\">1000</span>), <span class=\"literal\">false</span>)</span><br><span class=\"line\"></script> </span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"2-节流-throttle\"><a href=\"#2-节流-throttle\" class=\"headerlink\" title=\"2.节流(throttle)\"></a>2.节流(throttle)</h1><p>拖拽一个元素时,时刻获取到元素被拖拽的位置</p>\n<p>直接用drag事件,会频繁触发,容易造成卡顿</p>\n<p>节流:无论拖拽的速度多块,都每隔100ms触发一次</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><body></span><br><span class=\"line\"> <div id=<span class=\"string\">"div"</span> draggable=<span class=\"string\">"true"</span> </span><br><span class=\"line\"> style=<span class=\"string\">"border: 1px solid #ccc; width: 200px; height: 100px;"</span>></span><br><span class=\"line\"> 可拖拽</span><br><span class=\"line\"> </div></span><br><span class=\"line\"></body></span><br><span class=\"line\"><script></span><br><span class=\"line\"> <span class=\"keyword\">const</span> div = <span class=\"built_in\">document</span>.getElementById(<span class=\"string\">'div'</span>)</span><br><span class=\"line\"> <span class=\"keyword\">let</span> timer = <span class=\"literal\">null</span></span><br><span class=\"line\"></span><br><span class=\"line\"> div.addEventListener(<span class=\"string\">'drag'</span>, <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">e</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(timer) {</span><br><span class=\"line\"> <span class=\"keyword\">return</span></span><br><span class=\"line\"> }</span><br><span class=\"line\"></span><br><span class=\"line\"> timer = <span class=\"built_in\">setTimeout</span>(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(e.offsetX, e.offsetY)</span><br><span class=\"line\"> timer = <span class=\"literal\">null</span></span><br><span class=\"line\"> }, <span class=\"number\">100</span>)</span><br><span class=\"line\"> }, <span class=\"literal\">false</span>)</span><br><span class=\"line\"></script></span><br></pre></td></tr></table></figure></div>\n\n<p>封装throttle函数</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><body></span><br><span class=\"line\"> <div id=<span class=\"string\">"div"</span> draggable=<span class=\"string\">"true"</span> </span><br><span class=\"line\"> style=<span class=\"string\">"border: 1px solid #ccc; width: 200px; height: 100px;"</span>></span><br><span class=\"line\"> 可拖拽</span><br><span class=\"line\"> </div></span><br><span class=\"line\"></body></span><br><span class=\"line\"><script></span><br><span class=\"line\"> <span class=\"keyword\">const</span> div = <span class=\"built_in\">document</span>.getElementById(<span class=\"string\">'div'</span>)</span><br><span class=\"line\"> </span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">throttle</span>(<span class=\"params\">fn, delay = <span class=\"number\">100</span></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">let</span> timer = <span class=\"literal\">null</span></span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (timer) {</span><br><span class=\"line\"> <span class=\"keyword\">return</span></span><br><span class=\"line\"> }</span><br><span class=\"line\"> timer = <span class=\"built_in\">setTimeout</span>(<span class=\"function\">() =></span> {</span><br><span class=\"line\"> fn.apply(<span class=\"built_in\">this</span>, <span class=\"built_in\">arguments</span>)</span><br><span class=\"line\"> timer = <span class=\"literal\">null</span></span><br><span class=\"line\"> }, delay)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\"></span><br><span class=\"line\"> div.addEventListener(<span class=\"string\">'drag'</span>, throttle(<span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\">e</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(e.offsetX, e.offsetY)</span><br><span class=\"line\"> }, <span class=\"number\">200</span>), <span class=\"literal\">false</span>)</span><br><span class=\"line\"></script></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript基础01-js基本语法","url":"/2020/12/07/JavaScript%E5%9F%BA%E7%A1%8001-js%E5%9F%BA%E6%9C%AC%E8%AF%AD%E6%B3%95/","content":"<p>本文主要整理JavaScript的基本语法。</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-内置类型\"><a href=\"#1-内置类型\" class=\"headerlink\" title=\"1.内置类型\"></a>1.内置类型</h1><p>js中共为8种内置类型,这8种内置类型又分为两类:7种基本类型和对象(Object)。</p>\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/js%E5%86%85%E7%BD%AE%E7%B1%BB%E5%9E%8B.PNG\" alt=\"js内置类型\"></p>\n<hr>\n<h2 id=\"1-1-基本类型\"><a href=\"#1-1-基本类型\" class=\"headerlink\" title=\"1.1.基本类型\"></a>1.1.基本类型</h2><p>基本类型有7种:null,undefined,Boolean,number,BigInt,string,symbol</p>\n<hr>\n<h3 id=\"1-1-1-null\"><a href=\"#1-1-1-null\" class=\"headerlink\" title=\"1.1.1.null\"></a>1.1.1.null</h3><p>null是js的关键字,表示为此处没有对象。</p>\n<blockquote>\n<p>注意:对null使用typeof查看类型,返回的结果为 Object。这是js最初设计时的缺陷。</p>\n</blockquote>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"keyword\">typeof</span> <span class=\"literal\">null</span>)</span><br><span class=\"line\"><span class=\"comment\">// object</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"1-1-2-undefined\"><a href=\"#1-1-2-undefined\" class=\"headerlink\" title=\"1.1.2.undefined\"></a>1.1.2.undefined</h3><p>在js中,undefined表示缺少值,typeof一个没有值的变量会返回underfined。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> person;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"keyword\">typeof</span> person);</span><br><span class=\"line\"><span class=\"comment\">// undefined</span></span><br></pre></td></tr></table></figure></div>\n\n<p>undefined和null的区别:underfined和null值相等,但意义不同:</p>\n<p>null表示”没有对象”,即该处不应该有值:</p>\n<ul>\n<li>作为函数的参数,表示该函数的参数不是对象</li>\n<li>作为对象原型链的终点</li>\n</ul>\n<p>undefined表示”缺少值”,就是此处应该有一个值,但是还没有定义:</p>\n<ul>\n<li>变量被声明了,但没有赋值时,就等于undefined</li>\n<li>调用函数时,应该提供的参数没有提供,该参数等于undefined</li>\n<li>对象没有赋值的属性,该属性的值为undefined</li>\n<li>函数没有返回值时,默认返回undefined</li>\n</ul>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">typeof</span> <span class=\"literal\">undefined</span> <span class=\"comment\">// undefined</span></span><br><span class=\"line\"><span class=\"keyword\">typeof</span> <span class=\"literal\">null</span> <span class=\"comment\">// object</span></span><br><span class=\"line\"><span class=\"literal\">null</span> === <span class=\"literal\">undefined</span> <span class=\"comment\">// false</span></span><br><span class=\"line\"><span class=\"literal\">null</span> == <span class=\"literal\">undefined</span> <span class=\"comment\">// true</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"1-1-3-boolean-布尔值\"><a href=\"#1-1-3-boolean-布尔值\" class=\"headerlink\" title=\"1.1.3.boolean(布尔值)\"></a>1.1.3.boolean(布尔值)</h3><p>boolean表示两个值,真或假(true,false)。</p>\n<blockquote>\n<p>注意:任意js值都可以被转化为布尔值,使用Boolean()方法可以强制转换任意值为boolean类型。</p>\n</blockquote>\n<p>以下类型转化为boolean后值为false,其余的皆为true:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// null,undefined,0,-0,NaN,''</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"built_in\">Boolean</span>(<span class=\"literal\">null</span>));</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"built_in\">Boolean</span>(<span class=\"literal\">undefined</span>));</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"built_in\">Boolean</span>(<span class=\"number\">0</span>));</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"built_in\">Boolean</span>(-<span class=\"number\">0</span>));</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"built_in\">Boolean</span>(<span class=\"literal\">NaN</span>));</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"built_in\">Boolean</span>(<span class=\"string\">''</span>));</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"1-1-4-number\"><a href=\"#1-1-4-number\" class=\"headerlink\" title=\"1.1.4.number\"></a>1.1.4.number</h3><p>与其他语言区分整形和浮点型不同,在js中任何数字类型都可以用number表示,所有数字以双精度64位浮点数表示。</p>\n<blockquote>\n<p>注意:number中存在NaN(Not a Number),可以返回一个无法返回值的number类型:</p>\n</blockquote>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> number = <span class=\"number\">0</span>/<span class=\"number\">0</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"keyword\">typeof</span> number); <span class=\"comment\">// number</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(number); <span class=\"comment\">// NaN</span></span><br></pre></td></tr></table></figure></div>\n\n<p>上述代码中,我们定义number为0除以0,其结果在其他语言中一定会报错,但在js中我们可以得到变量类型number和返回值NaN。</p>\n<hr>\n<h3 id=\"1-1-5-BigInt\"><a href=\"#1-1-5-BigInt\" class=\"headerlink\" title=\"1.1.5.BigInt\"></a>1.1.5.BigInt</h3><p>BigInt是新增的内置类型,主要用于解决超过number类型在处理非常大的整数时丢失精度的问题。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"number\">9999999999999999</span>) <span class=\"comment\">// 10000000000000000</span></span><br></pre></td></tr></table></figure></div>\n\n<p>超过number类型最大整数后会自动为我们四舍五入,在一些情况下,这会危害到程序的安全性和可靠性:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"number\">9007199254740995</span>) <span class=\"comment\">// 9007199254740996</span></span><br></pre></td></tr></table></figure></div>\n\n<p>为了解决精度丢失的问题,引入了BigInt。</p>\n<p>要创建BigInt,我们可以在数组末尾+n,请在Chrome浏览器运行以下代码:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"number\">9007199254740995n</span>) <span class=\"comment\">// 9007199254740995n</span></span><br></pre></td></tr></table></figure></div>\n\n<p>也可以调用BigInt():</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(BigInt(<span class=\"number\">9007199254740995</span>)) <span class=\"comment\">//9007199254740996n</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"1-1-6-string\"><a href=\"#1-1-6-string\" class=\"headerlink\" title=\"1.1.6.string\"></a>1.1.6.string</h3><p>string类型用来表示0个或多个16位Unicode字符序列,在JavaScript中使用双引号与单引号没有任何区别,想要拼接两个字符串可以使用操作符(+)。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> str1 =<span class=\"string\">"hello"</span>;</span><br><span class=\"line\"><span class=\"keyword\">var</span> str2 = <span class=\"string\">'world'</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(str1 + <span class=\"string\">" "</span> + str2); <span class=\"comment\">// hello world</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h3 id=\"1-1-7-symbol\"><a href=\"#1-1-7-symbol\" class=\"headerlink\" title=\"1.1.7.symbol\"></a>1.1.7.symbol</h3><p>symbol是ES6新增的数据类型,表示独一无二的值,其本质是一种唯一标识符,可以用作对象的唯一属性名,避免出现添加的新方法与已有方法的冲突,这样其他人就不会改写和覆盖你已经设定好的属性值。</p>\n<p>声明方法:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> id = <span class=\"built_in\">Symbol</span>(<span class=\"string\">"id"</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"keyword\">typeof</span> id); <span class=\"comment\">// symbol</span></span><br></pre></td></tr></table></figure></div>\n\n<p>用法:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> id1 = <span class=\"built_in\">Symbol</span>(<span class=\"string\">'id'</span>);</span><br><span class=\"line\"><span class=\"keyword\">let</span> id2 = <span class=\"built_in\">Symbol</span>(<span class=\"string\">'id'</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(id1 == id2); <span class=\"comment\">// false</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"1-2-对象\"><a href=\"#1-2-对象\" class=\"headerlink\" title=\"1.2.对象\"></a>1.2.对象</h2><h3 id=\"1-2-1-对象是什么?\"><a href=\"#1-2-1-对象是什么?\" class=\"headerlink\" title=\"1.2.1.对象是什么?\"></a>1.2.1.对象是什么?</h3><p>在js中,对象其实就是一组数据和功能的集合,除了基本类型,其余都是对象类型了:</p>\n<ul>\n<li>布尔可以是对象(如果用 new 关键词定义)</li>\n<li>数字是可以对象(如果用 new 关键词定义)</li>\n<li>字符串是可以对象(如果用 new 关键词定义)</li>\n<li>日期永远都是对象</li>\n<li>算术永远都是对象</li>\n<li>正则表达式永远都是对象</li>\n<li>数组永远都是对象</li>\n<li>函数永远都是对象</li>\n<li>对象永远都是对象</li>\n</ul>\n<blockquote>\n<p>注意:null也是对象。</p>\n</blockquote>\n<hr>\n<h3 id=\"1-2-2-如何创建对象?\"><a href=\"#1-2-2-如何创建对象?\" class=\"headerlink\" title=\"1.2.2.如何创建对象?\"></a>1.2.2.如何创建对象?</h3><p>我们可以通过不同的方式构造对象:</p>\n<ul>\n<li>使用字面量创建对象</li>\n<li>使用new关键字构造对象</li>\n<li>定义对象构造器</li>\n</ul>\n<h4 id=\"1-2-2-1-字面量创建对象\"><a href=\"#1-2-2-1-字面量创建对象\" class=\"headerlink\" title=\"1.2.2.1.字面量创建对象\"></a>1.2.2.1.字面量创建对象</h4><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> person = {<span class=\"attr\">Name</span>:<span class=\"string\">"CalDey"</span>, <span class=\"attr\">age</span>:<span class=\"number\">23</span>, <span class=\"attr\">gender</span>:<span class=\"string\">"male"</span>};</span><br></pre></td></tr></table></figure></div>\n\n<p>如果对象的属性很多,也可以这样写:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> person = {</span><br><span class=\"line\"> Name:<span class=\"string\">"CalDey"</span>,</span><br><span class=\"line\"> age:<span class=\"number\">23</span>,</span><br><span class=\"line\"> gender:<span class=\"string\">"male"</span></span><br><span class=\"line\"> };</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h4 id=\"1-2-2-2-使用new关键字\"><a href=\"#1-2-2-2-使用new关键字\" class=\"headerlink\" title=\"1.2.2.2.使用new关键字\"></a>1.2.2.2.使用new关键字</h4><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> person = <span class=\"keyword\">new</span> <span class=\"built_in\">Object</span>();</span><br><span class=\"line\">person.Name = <span class=\"string\">"CalDey"</span>;</span><br><span class=\"line\">person.age = <span class=\"number\">23</span>;</span><br><span class=\"line\">gender = <span class=\"string\">"male"</span>; </span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h4 id=\"1-2-2-3-对象构造器\"><a href=\"#1-2-2-3-对象构造器\" class=\"headerlink\" title=\"1.2.2.3.对象构造器\"></a>1.2.2.3.对象构造器</h4><p>更多的创建对象方法会在面向对象编程时详细介绍</p>\n<hr>\n<h3 id=\"1-2-3-基本类型和引用类型复制变量值的区别\"><a href=\"#1-2-3-基本类型和引用类型复制变量值的区别\" class=\"headerlink\" title=\"1.2.3.基本类型和引用类型复制变量值的区别\"></a>1.2.3.基本类型和引用类型复制变量值的区别</h3><h4 id=\"1-2-3-1-基本类型\"><a href=\"#1-2-3-1-基本类型\" class=\"headerlink\" title=\"1.2.3.1.基本类型\"></a>1.2.3.1.基本类型</h4><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> num1 = <span class=\"number\">5</span>;</span><br><span class=\"line\"><span class=\"keyword\">var</span> num2 = num1;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(num1,num2); <span class=\"comment\">// 5,5</span></span><br><span class=\"line\"><span class=\"keyword\">var</span> num2 = <span class=\"number\">50</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(num1,num2); <span class=\"comment\">// 5,50</span></span><br></pre></td></tr></table></figure></div>\n\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/%E5%9F%BA%E6%9C%AC%E7%B1%BB%E5%9E%8B.PNG\" alt=\"基本类型\"></p>\n<p>num1中保存值是5,当使用num1值初始化num2后,num2也保存了值5,。但num1和num2中的5是相互独立,互不影响的,如果我们修改num2中的值为50,num1的值不会发生改变。</p>\n<hr>\n<h4 id=\"1-2-3-2-引用类型\"><a href=\"#1-2-3-2-引用类型\" class=\"headerlink\" title=\"1.2.3.2.引用类型\"></a>1.2.3.2.引用类型</h4><p>与基本类型不同,基本类型存储的是值,对象类型存储的是地址(指针)。基本类型的值保存在栈中,引用类型的值是同时保存在栈内存和堆内存的对象。当创建一个对象后,计算机会在内存中开辟了一个空间存放数据,但我们需要找到这个空间,这个空间会拥有一个地址(指针)。</p>\n<p>这个概念听起来比较抽象,通过下面示例我们会对这个概念有一个初步的理解:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> a = <span class=\"number\">5</span>;</span><br><span class=\"line\">a = <span class=\"number\">50</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(a);</span><br><span class=\"line\"><span class=\"comment\">// Uncaught TypeError: Assignment to constant variable.</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> Obj1 = [<span class=\"number\">0</span>];</span><br><span class=\"line\">Obj1 = [<span class=\"number\">1</span>];</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(Obj1);</span><br><span class=\"line\"><span class=\"comment\">// Uncaught TypeError: Assignment to constant variable.</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> Obj1 = [<span class=\"number\">0</span>];</span><br><span class=\"line\">Obj2 = Obj1;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"keyword\">typeof</span> Obj1); <span class=\"comment\">//object</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"keyword\">typeof</span> Obj2); <span class=\"comment\">//object</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(Obj1,Obj2); <span class=\"comment\">//0,0</span></span><br><span class=\"line\">Obj2[<span class=\"number\">0</span>] = <span class=\"number\">1</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(Obj1,Obj2); <span class=\"comment\">//1,1</span></span><br></pre></td></tr></table></figure></div>\n\n<p>上述代码我们通过const声明了三个变量,按道理来说const声明的变量是不会发生变化的,但事实上最后我们发现这个值能够改变。通过上述代码能够发现,const定义的基本类型变量确实不能变化,但如果是引用类型呢?通过下图我们可以得知,我们的变量只保存着指向对象的指针,也就是说,const只能保证对应的指针不变,修改对象的值并不会影响到指针。这个过程同时也很好的解释了引用类型值是如何复制的:</p>\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/%E5%BC%95%E7%94%A8%E7%B1%BB%E5%9E%8B.PNG\" alt=\"引用类型\"></p>\n<p>引用类型值的复制比较复杂,不同于基本类型值的复制是创建一个新值,引用类型值的复制可以看做是创建了一个新的指针指向我们存储在堆内存中的对象,原来的变量和新变量同时指向同一个对象,改变其中任何一个,另一个也会发生改变。</p>\n<p>由于对象(Object)是引用类型,所以在使用过程中会遇到浅拷贝和深拷贝的问题,这个概念在后续文章会详细解释,在此暂时略过。</p>\n<hr>\n<h1 id=\"2-tpyeof\"><a href=\"#2-tpyeof\" class=\"headerlink\" title=\"2.tpyeof\"></a>2.tpyeof</h1><p>typeof 对于基本类型,除了 null 都可以显示正确的类型</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">typeof</span> <span class=\"number\">1</span> <span class=\"comment\">// 'number'</span></span><br><span class=\"line\"><span class=\"keyword\">typeof</span> <span class=\"string\">'1'</span> <span class=\"comment\">// 'string'</span></span><br><span class=\"line\"><span class=\"keyword\">typeof</span> <span class=\"literal\">undefined</span> <span class=\"comment\">// 'undefined'</span></span><br><span class=\"line\"><span class=\"keyword\">typeof</span> <span class=\"literal\">true</span> <span class=\"comment\">// 'boolean'</span></span><br><span class=\"line\"><span class=\"keyword\">typeof</span> <span class=\"built_in\">Symbol</span>() <span class=\"comment\">// 'symbol'</span></span><br><span class=\"line\"><span class=\"keyword\">typeof</span> a <span class=\"comment\">// a 没有声明,但是还会显示 undefined</span></span><br></pre></td></tr></table></figure></div>\n\n<p>typeof 对于对象,除了函数都会显示 object</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">typeof</span> [] <span class=\"comment\">// 'object'</span></span><br><span class=\"line\"><span class=\"keyword\">typeof</span> {} <span class=\"comment\">// 'object'</span></span><br><span class=\"line\"><span class=\"keyword\">typeof</span> <span class=\"built_in\">console</span>.log <span class=\"comment\">// 'function'</span></span><br></pre></td></tr></table></figure></div>\n\n<p>对于 null 来说,虽然它是基本类型,但是会显示 object</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">typeof</span> <span class=\"literal\">null</span> <span class=\"comment\">// 'object'</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"3-类型转换\"><a href=\"#3-类型转换\" class=\"headerlink\" title=\"3.类型转换\"></a>3.类型转换</h1><h2 id=\"3-1-转布尔值\"><a href=\"#3-1-转布尔值\" class=\"headerlink\" title=\"3.1.转布尔值\"></a>3.1.转布尔值</h2><p>基本类型转换见<a href=\"#1-1-3-boolean-%E5%B8%83%E5%B0%94%E5%80%BC\">上文</a></p>\n<p>所有对象转换成boolean都为true。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> obj = {}</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log (<span class=\"built_in\">Boolean</span>(obj)); <span class=\"comment\">// true</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"3-2-对象转基本类型\"><a href=\"#3-2-对象转基本类型\" class=\"headerlink\" title=\"3.2.对象转基本类型\"></a>3.2.对象转基本类型</h2><p>toString()返回对象的字符串,valueOf()返回对象的原始值:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> obj = <span class=\"keyword\">new</span> <span class=\"built_in\">Number</span>(<span class=\"string\">'123456'</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"keyword\">typeof</span> obj); <span class=\"comment\">// object</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj.toString()); <span class=\"comment\">// 123456</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj.valueOf());</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"keyword\">typeof</span> obj.toString()); <span class=\"comment\">// string</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"keyword\">typeof</span> obj.valueOf()); <span class=\"comment\">// number</span></span><br></pre></td></tr></table></figure></div>\n\n<p>对象转换成基本类型时,优先调用valueOf然后调用toString。这两种方法可以重写:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> obj = {</span><br><span class=\"line\"> <span class=\"function\"><span class=\"title\">toString</span>(<span class=\"params\"></span>)</span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log (<span class=\"string\">"toString"</span>)</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"string\">"Hello World"</span> </span><br><span class=\"line\"></span><br><span class=\"line\"> },</span><br><span class=\"line\"> <span class=\"function\"><span class=\"title\">valueOf</span>(<span class=\"params\"></span>)</span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">"valueOf"</span>)</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"number\">123</span>; </span><br><span class=\"line\"> }</span><br><span class=\"line\"> };</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log (<span class=\"string\">"obj="</span> + obj); <span class=\"comment\">// obj=123</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log (<span class=\"string\">"obj="</span> + obj.toString()); <span class=\"comment\">// obj=Hello World</span></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"comment\">// 先打印出valueOf和obj=123,后打印出toString和obj=Hello World</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"3-3-四则运算符\"><a href=\"#3-3-四则运算符\" class=\"headerlink\" title=\"3.3.四则运算符\"></a>3.3.四则运算符</h2><p>在加法运算中,如果一方为字符串类型,就会把另一方也转化为字符串;其他运算中,一方为数字,就会把另一方也转化成数字;在某些情况下,如果加法中有对象,那么先要把对象转化为原始值再进行计算:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"number\">1</span> + <span class=\"string\">'23'</span>) <span class=\"comment\">// 123</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"number\">1</span> * <span class=\"string\">'23'</span>) <span class=\"comment\">// 23</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"number\">1</span> - <span class=\"string\">'23'</span>) <span class=\"comment\">// -22</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log([<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>] + [<span class=\"number\">1</span>,<span class=\"number\">2</span>]) <span class=\"comment\">// 1,2,31,2</span></span><br><span class=\"line\"><span class=\"comment\">// [1,2,3].toString()->'1,2,3'</span></span><br><span class=\"line\"><span class=\"comment\">// [1,2].toString()->'1,2'</span></span><br><span class=\"line\"><span class=\"comment\">// console.log('1,2,3' + '1,2')</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log([].toString()) <span class=\"comment\">// </span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log({}.toString()) <span class=\"comment\">// [object Object]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log([<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>] + {}) <span class=\"comment\">// 1,2,3[object Object]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"number\">4</span> * []) <span class=\"comment\">// 0</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"number\">4</span> * [<span class=\"number\">1</span>,<span class=\"number\">2</span>]) <span class=\"comment\">// NaN</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"number\">4</span> - [<span class=\"number\">1</span>,<span class=\"number\">2</span>]) <span class=\"comment\">// NaN</span></span><br></pre></td></tr></table></figure></div>\n\n\n\n<blockquote>\n<p>注意:在对非数字使用加或减操作符时,该操作符会像Number()一样对这个值进行转换。</p>\n</blockquote>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(+ <span class=\"string\">'01'</span>) <span class=\"comment\">// 1</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(+ <span class=\"literal\">false</span>) <span class=\"comment\">// 0</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(+ <span class=\"number\">1.1</span>) <span class=\"comment\">// 1.1</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(+ <span class=\"string\">'a'</span>) <span class=\"comment\">// NaN</span></span><br><span class=\"line\"><span class=\"keyword\">var</span> o = {</span><br><span class=\"line\"> valueOf()</span><br><span class=\"line\"> {</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><br><span class=\"line\"><span class=\"built_in\">console</span>.log(+ o) <span class=\"comment\">// -1</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(- o) <span class=\"comment\">// 1</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"3-4-关系运算符\"><a href=\"#3-4-关系运算符\" class=\"headerlink\" title=\"3.4.关系运算符\"></a>3.4.关系运算符</h2><p>需要注意的是,如果其中一方是对象,那么需要先调用valueOf()返回值进行比较,如果对象没有valueOf()方法,则调用toString()方法进行比较:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> obj = {</span><br><span class=\"line\"> <span class=\"function\"><span class=\"title\">valueOf</span>(<span class=\"params\"></span>)</span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'valueOf'</span>)</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"number\">2</span></span><br><span class=\"line\"> },</span><br><span class=\"line\"> <span class=\"function\"><span class=\"title\">toString</span>(<span class=\"params\"></span>)</span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'toString'</span>)</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"string\">'1'</span></span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(obj > <span class=\"number\">1</span>) <span class=\"comment\">// true</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"number\">1</span> + obj) <span class=\"comment\">// 3->obj = 2</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"4-函数\"><a href=\"#4-函数\" class=\"headerlink\" title=\"4.函数\"></a>4.函数</h1><h2 id=\"4-1-什么是函数?\"><a href=\"#4-1-什么是函数?\" class=\"headerlink\" title=\"4.1.什么是函数?\"></a>4.1.什么是函数?</h2><p>对于任何语言来说,函数都是一个很核心的概念。通过函数可以封装任意条语句,我们可以在任何地方,任何时候调用执行。</p>\n<p>我们通过function关键字来声明一个函数,后面跟一组参数以及函数体:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">functionName</span>(<span class=\"params\">arg0,arg1,...,argN</span>) </span>{</span><br><span class=\"line\"> statements</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>下面是一个函数示例,我们可以通过调用函数名sayHi()来传递参数:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">sayHi</span>(<span class=\"params\">name, message</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'Hello '</span> + name + <span class=\"string\">','</span> + message)</span><br><span class=\"line\">}</span><br><span class=\"line\">sayHi(<span class=\"string\">'CalDey'</span>,<span class=\"string\">'Nice to meet you'</span>)</span><br><span class=\"line\"><span class=\"comment\">// Hello CalDey,Nice to meet you</span></span><br></pre></td></tr></table></figure></div>\n\n<p>函数在定义时不必指定返回值,如果需要的话,任何函数在任何时候都可以通过return返回值:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">sum</span>(<span class=\"params\">num1, num2</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> num1 + num2;</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">var</span> res = sum(<span class=\"number\">1</span>,<span class=\"number\">5</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(res) <span class=\"comment\">// 6</span></span><br></pre></td></tr></table></figure></div>\n\n<p>sum()函数的作用是返回两个值相加的结果,我们可以通过声明一个变量来接收这个结果。</p>\n<blockquote>\n<p>注意:这个函数在return语句后会立即停止并退出,因此,return后的任何代码都不会执行。</p>\n</blockquote>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">sum</span>(<span class=\"params\">num1, num2</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> num1 + num2;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'Hello World'</span>) <span class=\"comment\">// 永远不会执行</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>return语句也可以不带任何返回值,这种用法一般发生于我们希望函数停止执行而又不需要返回值的情况下:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">sum</span>(<span class=\"params\">num1, num2</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span>;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'num1'</span> + <span class=\"string\">'num2'</span>) <span class=\"comment\">// 永远不会执行</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"4-2-理解参数\"><a href=\"#4-2-理解参数\" class=\"headerlink\" title=\"4.2.理解参数\"></a>4.2.理解参数</h2><p>首先我们来看一段代码:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">sayHi</span>(<span class=\"params\">name, message</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'Hello '</span> + name + <span class=\"string\">','</span> + message)</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">arguments</span>.length) <span class=\"comment\">// 5</span></span><br><span class=\"line\">}</span><br><span class=\"line\">sayHi(<span class=\"string\">'CalDey'</span>,<span class=\"string\">'Nice to meet you'</span>, <span class=\"string\">'a'</span>, <span class=\"string\">'b'</span>,<span class=\"string\">'c'</span>)</span><br><span class=\"line\"><span class=\"comment\">// Hello CalDey,Nice to meet you</span></span><br></pre></td></tr></table></figure></div>\n\n<p>我们只定义了两个命名参数,但我们一共传递给函数5个参数,然而函数并未报错,而且函数确实接受到了5个参数。导致这种现象的原因是参数是用一个数组表示的,函数接受的始终是这个数组,并不关心数组中具体有哪些参数,因此,即使我们不声明命名参数,函数一样也可以接收到参数,在函数体内可以通过arguments对象来访问参数数组,从而获取传递给函数的每一个值:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">sayHi</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'Hello '</span> + <span class=\"built_in\">arguments</span>[<span class=\"number\">0</span>] + <span class=\"string\">','</span> + <span class=\"built_in\">arguments</span>[<span class=\"number\">1</span>])</span><br><span class=\"line\">}</span><br><span class=\"line\">sayHi(<span class=\"string\">'CalDey'</span>, <span class=\"string\">'Nice to meet you'</span>)</span><br><span class=\"line\"><span class=\"comment\">// Hello CalDey,Nice to meet you</span></span><br></pre></td></tr></table></figure></div>\n\n<p>命名参数也可以和arguments对象一起使用,它们的值永远保持同步:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">sum</span>(<span class=\"params\">num1, num2</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">arguments</span>[<span class=\"number\">1</span>] = <span class=\"number\">10</span>; <span class=\"comment\">// num2会重写为10</span></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">arguments</span>[<span class=\"number\">0</span>] + num2); <span class=\"comment\">// 5 + 10</span></span><br><span class=\"line\">}</span><br><span class=\"line\">sum(<span class=\"number\">5</span>, <span class=\"number\">50</span>)</span><br></pre></td></tr></table></figure></div>\n\n<blockquote>\n<p>注意:没有传递值的命名参数和未初始化变量一样,将默认添加undefined值。</p>\n</blockquote>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">sum</span>(<span class=\"params\">num1, num2</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(num2); <span class=\"comment\">// undefined</span></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"built_in\">arguments</span>[<span class=\"number\">1</span>]); <span class=\"comment\">// undefined</span></span><br><span class=\"line\">}</span><br><span class=\"line\">sum(<span class=\"number\">5</span>)</span><br></pre></td></tr></table></figure></div>\n\n<p>还需要注意的是,实参相当于给形参传值,如果实参有具体值会替代掉形参中的默认值:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// es5</span></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">sum</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">var</span> a = <span class=\"built_in\">arguments</span>[<span class=\"number\">0</span>] || <span class=\"number\">1</span>;</span><br><span class=\"line\"> <span class=\"keyword\">var</span> b = <span class=\"built_in\">arguments</span>[<span class=\"number\">1</span>] || <span class=\"number\">2</span>;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a +b);</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\">sum() <span class=\"comment\">// 3</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// es6</span></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">sum1</span>(<span class=\"params\">a = <span class=\"literal\">undefined</span>, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a + b);</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">sum2</span>(<span class=\"params\">a = <span class=\"number\">1</span>, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a + b);</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\">sum1(<span class=\"number\">1</span>, <span class=\"number\">2</span>) <span class=\"comment\">// 3</span></span><br><span class=\"line\">sum2(<span class=\"literal\">undefined</span>, <span class=\"number\">2</span>) <span class=\"comment\">// 3</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"4-3-函数,对象,方法的区别\"><a href=\"#4-3-函数,对象,方法的区别\" class=\"headerlink\" title=\"4.3.函数,对象,方法的区别\"></a>4.3.函数,对象,方法的区别</h2><p>在js中,几乎万物皆为对象,函数是对一段js代码的封装,函数可以封装在对象中,方法是绑定到对象身上的函数:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 对象</span></span><br><span class=\"line\"><span class=\"keyword\">var</span> xiaoming = {</span><br><span class=\"line\"> name: <span class=\"string\">'小明'</span>,</span><br><span class=\"line\"> birth: <span class=\"number\">2000</span>,</span><br><span class=\"line\"> <span class=\"comment\">// 函数</span></span><br><span class=\"line\"> age: <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"number\">20</span></span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(xiaoming.age) <span class=\"comment\">// function() { return 20 }</span></span><br><span class=\"line\"><span class=\"comment\">// 方法</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(xiaoming.age()) <span class=\"comment\">// 20</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript进阶01-AO和GO","url":"/2021/02/19/JavaScript%E8%BF%9B%E9%98%B601-AO%E5%92%8CGO/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<p>在学习作用域前,首先要彻底弄懂AO和GO</p>\n<h1 id=\"1-AO\"><a href=\"#1-AO\" class=\"headerlink\" title=\"1.AO\"></a>1.AO</h1><p>AO Activetion Object 活跃对象(函数上下文)</p>\n<p>AO的执行过程:</p>\n<ul>\n<li>1.寻找函数中的形参和变量声明</li>\n<li>2.实参赋值给形参</li>\n<li>3.寻找函数声明,赋值</li>\n<li>4.执行</li>\n</ul>\n<p>AO的执行顺序:<br>形参 -> 变量声明 -> 实参 -> 函数声明 -> 赋值</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\">a, b</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a); <span class=\"comment\">// 1</span></span><br><span class=\"line\"> c = <span class=\"number\">0</span>;</span><br><span class=\"line\"> <span class=\"keyword\">var</span> c;</span><br><span class=\"line\"> a = <span class=\"number\">5</span>;</span><br><span class=\"line\"> b = <span class=\"number\">6</span>;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(b); <span class=\"comment\">// 6</span></span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">b</span>(<span class=\"params\"></span>) </span>{}</span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">d</span>(<span class=\"params\"></span>) </span>{}</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(d); <span class=\"comment\">// function d() {}</span></span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\">test(<span class=\"number\">1</span>);</span><br></pre></td></tr></table></figure></div>\n\n<p>AO的执行过程如下:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">AO = {</span><br><span class=\"line\"> a: <span class=\"literal\">undefined</span>(形参) -> <span class=\"number\">1</span>(实参)-> <span class=\"number\">5</span>(赋值)</span><br><span class=\"line\"> b: <span class=\"literal\">undefined</span>(形参) -> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">b</span> (<span class=\"params\"></span>) </span>{}(函数声明) -> <span class=\"number\">6</span>(赋值)</span><br><span class=\"line\"> c: <span class=\"literal\">undefined</span>(变量声明) -> <span class=\"number\">0</span>(赋值)</span><br><span class=\"line\"> d: <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">d</span>(<span class=\"params\"></span>) </span>{}(函数声明)</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>通过AO的执行顺序便可以轻松区分复杂函数中变量在不同位置的值,注意变量提升和函数提升</p>\n<blockquote>\n<p>注意:AO是函数上下文,每一个函数都有自己的AO</p>\n</blockquote>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> a;</span><br><span class=\"line\"> a = <span class=\"number\">1</span>;</span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">a</span>(<span class=\"params\"></span>) </span>{}</span><br><span class=\"line\"> <span class=\"keyword\">var</span> a = <span class=\"number\">2</span>;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a)</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(test()) <span class=\"comment\">// function a() {}</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">AO = {</span><br><span class=\"line\"> a: <span class=\"literal\">undefined</span> -> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">a</span>(<span class=\"params\"></span>) </span>{} <span class=\"comment\">// 变量提升后直接return</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> a = <span class=\"number\">1</span>;</span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">a</span>(<span class=\"params\"></span>) </span>{}</span><br><span class=\"line\"> <span class=\"keyword\">var</span> a = <span class=\"number\">2</span>;</span><br><span class=\"line\"> <span class=\"keyword\">return</span> a;</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(test()) <span class=\"comment\">// 2</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">AO = {</span><br><span class=\"line\"> a: <span class=\"literal\">undefined</span> -> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">a</span>(<span class=\"params\"></span>) </span>{} -> <span class=\"number\">1</span> -> <span class=\"number\">2</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"2-GO\"><a href=\"#2-GO\" class=\"headerlink\" title=\"2.GO\"></a>2.GO</h1><p>GO Global Object 全局上下文</p>\n<p>GO的执行顺序:<br>变量声明 -> 函数声明 -> 赋值</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> a = <span class=\"number\">1</span>;</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">a</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">2</span>);</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(a);</span><br></pre></td></tr></table></figure></div>\n\n<p>GO的执行过程如下:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">GO = {</span><br><span class=\"line\"> a: <span class=\"literal\">undefined</span>(变量声明) -> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">a</span>(<span class=\"params\"></span>) </span>{}(函数声明) -> <span class=\"number\">1</span>(赋值)</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<blockquote>\n<p>注意:var a = 1分为变量提升和变量赋值</p>\n</blockquote>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(a, b);</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">a</span>(<span class=\"params\"></span>) </span>{}</span><br><span class=\"line\"><span class=\"keyword\">var</span> b = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{}</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">GO = {</span><br><span class=\"line\"> a: <span class=\"literal\">undefined</span> -> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">a</span>(<span class=\"params\"></span>) </span>{}</span><br><span class=\"line\"> b: <span class=\"literal\">undefined</span> -> <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{}(赋值)</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<blockquote>\n<p>注意:console的发生位置在提升后,赋值前,因此b此时为undefined</p>\n</blockquote>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test1</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">1</span>);</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test2</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"number\">2</span>);</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\">test2();</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test3</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> test1();</span><br><span class=\"line\"> test2()</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\">test3();</span><br></pre></td></tr></table></figure></div>\n\n<p>GO中存储的全局函数可随时被重复调用</p>\n<hr>\n<h1 id=\"3-预编译\"><a href=\"#3-预编译\" class=\"headerlink\" title=\"3.预编译\"></a>3.预编译</h1><p>预编译阶段只发生变量声明和函数声明,没有初始化行为(赋值),只有执行阶段才进行变量初始化</p>\n<h1 id=\"4-AO-GO面试题\"><a href=\"#4-AO-GO面试题\" class=\"headerlink\" title=\"4.AO,GO面试题\"></a>4.AO,GO面试题</h1><p>第一题</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">var</span> a = b = <span class=\"number\">1</span>;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(b); <span class=\"comment\">// 1</span></span><br><span class=\"line\">}</span><br><span class=\"line\">test();</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">GO = {</span><br><span class=\"line\"> b: <span class=\"number\">1</span></span><br><span class=\"line\">}</span><br><span class=\"line\">AO = {</span><br><span class=\"line\"> a: <span class=\"literal\">undefined</span> -> <span class=\"number\">1</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<blockquote>\n<p>注意: 函数中b未声明直接赋值为1,b为全局变量</p>\n</blockquote>\n<p>imply global 暗示全局变量</p>\n<p>第二题</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> b = <span class=\"number\">3</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(a);</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">a</span>(<span class=\"params\">a</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a);</span><br><span class=\"line\"> <span class=\"keyword\">var</span> a = <span class=\"number\">2</span>;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a);</span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">a</span>(<span class=\"params\"></span>) </span>{}</span><br><span class=\"line\"> <span class=\"keyword\">var</span> b = <span class=\"number\">5</span>;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(b);</span><br><span class=\"line\">}</span><br><span class=\"line\">a(<span class=\"number\">1</span>);</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">GO: {</span><br><span class=\"line\"> a: <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">a</span>(<span class=\"params\"></span>) </span>{}</span><br><span class=\"line\"> b: <span class=\"literal\">undefined</span> -> <span class=\"number\">3</span></span><br><span class=\"line\">}</span><br><span class=\"line\">AO: {</span><br><span class=\"line\"> a: <span class=\"literal\">undefined</span> -> <span class=\"number\">1</span> -> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">a</span>(<span class=\"params\"></span>) </span>{} -> <span class=\"number\">2</span></span><br><span class=\"line\"> b: <span class=\"literal\">undefined</span> -> <span class=\"number\">5</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>第三题</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">a = <span class=\"number\">1</span>;</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a);</span><br><span class=\"line\"> a = <span class=\"number\">2</span>;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a);</span><br><span class=\"line\"> <span class=\"keyword\">var</span> a = <span class=\"number\">3</span>;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a);</span><br><span class=\"line\">}</span><br><span class=\"line\">test()</span><br><span class=\"line\"><span class=\"keyword\">var</span> a;</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">GO = {</span><br><span class=\"line\"> a: <span class=\"literal\">undefined</span> -> <span class=\"number\">1</span></span><br><span class=\"line\"> test: <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\"></span>) </span>{}</span><br><span class=\"line\">}</span><br><span class=\"line\">AO = {</span><br><span class=\"line\"> a: <span class=\"literal\">undefined</span> -> <span class=\"number\">2</span> -> <span class=\"number\">3</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>第四题</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(b);</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (a) {</span><br><span class=\"line\"> <span class=\"keyword\">var</span> b = <span class=\"number\">2</span>;</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(b);</span><br><span class=\"line\"></span><br><span class=\"line\"> c = <span class=\"number\">3</span>;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(c);</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">var</span> a;</span><br><span class=\"line\">test();</span><br><span class=\"line\">a = <span class=\"number\">1</span>;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(a);</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">GO = {</span><br><span class=\"line\"> a: <span class=\"literal\">undefined</span> -> <span class=\"number\">1</span></span><br><span class=\"line\"> test: <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\"></span>) </span>{}</span><br><span class=\"line\">}</span><br><span class=\"line\">AO = {</span><br><span class=\"line\"> b: <span class=\"literal\">undefined</span> <span class=\"comment\">// 预编译只看判断条件中的变量声明</span></span><br><span class=\"line\"> c: <span class=\"number\">3</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"4-思考题\"><a href=\"#4-思考题\" class=\"headerlink\" title=\"4.思考题\"></a>4.思考题</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">a = <span class=\"number\">1</span>;</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\">e</span>) </span>{</span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">e</span>(<span class=\"params\"></span>) </span>{}</span><br><span class=\"line\"> <span class=\"built_in\">arguments</span>[<span class=\"number\">0</span>] = <span class=\"number\">2</span>;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(e);</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (a) {</span><br><span class=\"line\"> <span class=\"keyword\">var</span> b = <span class=\"number\">3</span>;</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">var</span> c;</span><br><span class=\"line\"> a = <span class=\"number\">4</span>;</span><br><span class=\"line\"> <span class=\"keyword\">var</span> a;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(b);</span><br><span class=\"line\"> f = <span class=\"number\">5</span>;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(c);</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a);</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">var</span> a;</span><br><span class=\"line\">test(<span class=\"number\">1</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(a);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(f);</span><br></pre></td></tr></table></figure></div>\n\n<details>\n <summary>点我查看答案</summary>\n <div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// arguments[0] = 2 是赋值</span></span><br><span class=\"line\">GO = {</span><br><span class=\"line\"> a: <span class=\"literal\">undefined</span> -> <span class=\"number\">1</span></span><br><span class=\"line\"> test: <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\"></span>) </span>{}</span><br><span class=\"line\"> f: <span class=\"number\">5</span></span><br><span class=\"line\">}</span><br><span class=\"line\">AO = {</span><br><span class=\"line\"> e: <span class=\"literal\">undefined</span> -> <span class=\"number\">1</span> -> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">e</span>(<span class=\"params\"></span>) </span>{} -> <span class=\"number\">2</span></span><br><span class=\"line\"> a: <span class=\"literal\">undefined</span> -> <span class=\"number\">4</span></span><br><span class=\"line\"> b: <span class=\"literal\">undefined</span></span><br><span class=\"line\"> c: <span class=\"literal\">undefined</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n</details>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript","JavaScript进阶"]},{"title":"JavaScript常见面试题汇总","url":"/2021/02/23/JavaScript%E5%B8%B8%E8%A7%81%E9%9D%A2%E8%AF%95%E9%A2%98%E6%B1%87%E6%80%BB/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-var和let,const的区别?\"><a href=\"#1-var和let,const的区别?\" class=\"headerlink\" title=\"1.var和let,const的区别?\"></a>1.var和let,const的区别?</h1><p>ES5:var存在变量提升,变量会被挂载到window上<br>ES6:let,const不存在变量提升,不会挂载到window,存在块级作用域</p>\n<p>var和let声明的是变量可以修改,const声明常量,不能修改</p>\n<hr>\n<h1 id=\"2-typeof返回哪些类型?\"><a href=\"#2-typeof返回哪些类型?\" class=\"headerlink\" title=\"2.typeof返回哪些类型?\"></a>2.typeof返回哪些类型?</h1><p>能够正常识别所有基本类型(undefined, number, string, boolean, symbol)<br>只能识别是否是引用类型,不能区别具体类型(typeof null = ‘object’)<br>可以识别出函数</p>\n<table>\n<thead>\n<tr>\n<th>表达式</th>\n<th>返回值</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>typeof undefined</td>\n<td>‘undefined’</td>\n</tr>\n<tr>\n<td>typeof null</td>\n<td>‘object’</td>\n</tr>\n<tr>\n<td>typeof true</td>\n<td>‘boolean’</td>\n</tr>\n<tr>\n<td>typeof 123</td>\n<td>‘number’</td>\n</tr>\n<tr>\n<td>typeof “abc”</td>\n<td>‘string’</td>\n</tr>\n<tr>\n<td>typeof function() {}</td>\n<td>‘function’</td>\n</tr>\n<tr>\n<td>typeof {}</td>\n<td>‘object’</td>\n</tr>\n<tr>\n<td>typeof []</td>\n<td>‘object’</td>\n</tr>\n</tbody></table>\n<hr>\n<h1 id=\"3-强制类型转换和隐式类型转换\"><a href=\"#3-强制类型转换和隐式类型转换\" class=\"headerlink\" title=\"3.强制类型转换和隐式类型转换\"></a>3.强制类型转换和隐式类型转换</h1><p>强制转换:parseInt,parseFloat,toString…</p>\n<p>隐式转换:if,逻辑运算,==,+拼接字符串</p>\n<hr>\n<h1 id=\"4-手写深度比较\"><a href=\"#4-手写深度比较\" class=\"headerlink\" title=\"4.手写深度比较\"></a>4.手写深度比较</h1><p>实现如下效果:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> obj1 = {<span class=\"attr\">a</span>: <span class=\"number\">10</span>, <span class=\"attr\">b</span>: { <span class=\"attr\">x</span>: <span class=\"number\">100</span>, <span class=\"attr\">y</span>: <span class=\"number\">200</span> }}</span><br><span class=\"line\"><span class=\"keyword\">const</span> obj2 = {<span class=\"attr\">a</span>: <span class=\"number\">10</span>, <span class=\"attr\">b</span>: { <span class=\"attr\">x</span>: <span class=\"number\">100</span>, <span class=\"attr\">y</span>: <span class=\"number\">200</span> }}</span><br><span class=\"line\">isEqual(obj1, obj2) === <span class=\"literal\">true</span></span><br></pre></td></tr></table></figure></div>\n\n<p>思路:</p>\n<p>①首先判断传入参数是否是基本类型,直接比较<br>②传入参数可能是同一个对象或数组,直接比较<br>③传入的两个参数都是对象或数组,先比较两者长度是否相等<br>④递归比较两者每个键对应的值是否相等</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">isObject</span>(<span class=\"params\">obj</span>) </span>{</span><br><span class=\"line\"> <span class=\"comment\">// 判断是否为对象或数组</span></span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"keyword\">typeof</span> obj === <span class=\"string\">'object'</span> && obj !== <span class=\"literal\">null</span></span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">isEqual</span>(<span class=\"params\">obj1, obj2</span>) </span>{</span><br><span class=\"line\"> <span class=\"comment\">// 如果为基本类型,直接比较</span></span><br><span class=\"line\"> <span class=\"keyword\">if</span> (!isObject(obj1) || !isObject(obj2)) {</span><br><span class=\"line\"> <span class=\"keyword\">return</span> obj1 === obj2</span><br><span class=\"line\"> };</span><br><span class=\"line\"> <span class=\"comment\">// 如果自己和自己比较</span></span><br><span class=\"line\"> <span class=\"keyword\">if</span> (obj1 === obj2) <span class=\"keyword\">return</span> <span class=\"literal\">true</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\">const</span> obj1Keys = <span class=\"built_in\">Object</span>.keys(obj1)</span><br><span class=\"line\"> <span class=\"keyword\">const</span> obj2Keys = <span class=\"built_in\">Object</span>.keys(obj2)</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (obj1Keys.length !== obj2Keys.length) {</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 class=\"comment\">// 递归比较</span></span><br><span class=\"line\"> <span class=\"keyword\">for</span> (<span class=\"keyword\">let</span> key <span class=\"keyword\">in</span> obj1) {</span><br><span class=\"line\"> <span class=\"comment\">// 比较key对应的value</span></span><br><span class=\"line\"> <span class=\"keyword\">const</span> res = isEqual(obj1[key], obj2[key])</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (!res) {</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 class=\"keyword\">return</span> <span class=\"literal\">true</span></span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">const</span> obj1 = {<span class=\"attr\">a</span>: <span class=\"number\">10</span>, <span class=\"attr\">b</span>: { <span class=\"attr\">x</span>: <span class=\"number\">100</span>, <span class=\"attr\">y</span>: <span class=\"number\">200</span> }}</span><br><span class=\"line\"><span class=\"keyword\">const</span> obj2 = {<span class=\"attr\">a</span>: <span class=\"number\">10</span>, <span class=\"attr\">b</span>: { <span class=\"attr\">x</span>: <span class=\"number\">100</span>, <span class=\"attr\">y</span>: <span class=\"number\">200</span>, <span class=\"attr\">z</span>: <span class=\"number\">300</span> }}</span><br><span class=\"line\"><span class=\"comment\">// const obj1 = [0, 1, 2]</span></span><br><span class=\"line\"><span class=\"comment\">// const obj2 = [0, 1, 2, 3]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(isEqual(obj1, obj2))</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"5-split-和join-的区别\"><a href=\"#5-split-和join-的区别\" class=\"headerlink\" title=\"5.split()和join()的区别\"></a>5.split()和join()的区别</h1><p>split() 字符串 -> 数组<br>join() 数组 -> 字符串</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"string\">'1-2-3'</span>.split(<span class=\"string\">'-'</span>)) <span class=\"comment\">// [1, 2, 3]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log([<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>].join(<span class=\"string\">'-'</span>)) <span class=\"comment\">// '1-2-3'</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"6-pop,push,unshift,shift分别是什么?\"><a href=\"#6-pop,push,unshift,shift分别是什么?\" class=\"headerlink\" title=\"6.pop,push,unshift,shift分别是什么?\"></a>6.pop,push,unshift,shift分别是什么?</h1><p>pop: 删除末尾的元素,并返回该元素,会修改原数组</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>, <span class=\"number\">4</span>]</span><br><span class=\"line\">newArr = arr.pop()</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(newArr, arr)</span><br></pre></td></tr></table></figure></div>\n\n<p>shift:删除首位的元素,并返回该元素,会修改原数组</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>, <span class=\"number\">4</span>]</span><br><span class=\"line\">newArr = arr.shift()</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(newArr, arr)</span><br></pre></td></tr></table></figure></div>\n\n<p>push:添加元素到末尾,<font color=#ff503e><strong>返回修改后数组的长度</strong></font>,会修改原数组</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>, <span class=\"number\">4</span>]</span><br><span class=\"line\">newArr = arr.push(<span class=\"number\">50</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(newArr, arr)</span><br></pre></td></tr></table></figure></div>\n\n<p>unshift:添加元素到首位,<font color=#ff503e><strong>返回修改后数组的长度</strong></font>,会修改原数组</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>, <span class=\"number\">4</span>]</span><br><span class=\"line\">newArr = arr.unshift(<span class=\"number\">50</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(newArr, arr)</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"7-数组API中有哪些是纯函数?\"><a href=\"#7-数组API中有哪些是纯函数?\" class=\"headerlink\" title=\"7.数组API中有哪些是纯函数?\"></a>7.数组API中有哪些是纯函数?</h1><p>纯函数:不改变原数组(无副作用),并返回一个新数组</p>\n<p>concat:合并数组</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>, <span class=\"number\">4</span>]</span><br><span class=\"line\">newArr = arr.shift()</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(newArr, arr)</span><br></pre></td></tr></table></figure></div>\n\n<p>map:对数组内每个元素执行回调操作</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>, <span class=\"number\">4</span>]</span><br><span class=\"line\">newArr = arr.map(<span class=\"function\">(<span class=\"params\">num</span>) =></span> num * <span class=\"number\">10</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(newArr, arr)</span><br></pre></td></tr></table></figure></div>\n\n<p>filter:过滤数组内元素</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>, <span class=\"number\">4</span>, <span class=\"number\">50</span>, <span class=\"number\">60</span>]</span><br><span class=\"line\">newArr = arr.filter(<span class=\"function\">(<span class=\"params\">num</span>) =></span> num > <span class=\"number\">10</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(newArr, arr)</span><br></pre></td></tr></table></figure></div>\n\n<p>slice:对一维数组的深拷贝,本质上是浅拷贝</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">arr = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>, <span class=\"number\">4</span>]</span><br><span class=\"line\">newArr = arr.slice()</span><br><span class=\"line\">arr.push(<span class=\"number\">50</span>)</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(newArr, arr)</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"8-数组slice和splice的区别\"><a href=\"#8-数组slice和splice的区别\" class=\"headerlink\" title=\"8.数组slice和splice的区别\"></a>8.数组slice和splice的区别</h1><p>slice切片 纯函数</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">arr1 = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>, <span class=\"number\">4</span>, <span class=\"number\">5</span>, <span class=\"number\">6</span>]</span><br><span class=\"line\">arr2 = arr1.slice(<span class=\"number\">1</span>,<span class=\"number\">3</span>) <span class=\"comment\">// [2, 3]</span></span><br><span class=\"line\">arr3 = arr1.slice(<span class=\"number\">2</span>) <span class=\"comment\">// [3, 4, 5, 6]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr1, arr2, arr3)</span><br></pre></td></tr></table></figure></div>\n\n<p>splice剪切 非纯函数</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">arr1 = [<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">3</span>, <span class=\"number\">4</span>, <span class=\"number\">5</span>, <span class=\"number\">6</span>]</span><br><span class=\"line\"><span class=\"comment\">// 剪切并替换内容</span></span><br><span class=\"line\">arr2 = arr1.splice(<span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"string\">'a'</span>, <span class=\"string\">'b'</span>, <span class=\"string\">'c'</span>) </span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr1) <span class=\"comment\">// [1, "a", "b", "c", 4, 5, 6]</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(arr2) <span class=\"comment\">// [2, 3]</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"9-10-20-30-map-parseInt\"><a href=\"#9-10-20-30-map-parseInt\" class=\"headerlink\" title=\"9. [10, 20, 30].map(parseInt)\"></a>9. [10, 20, 30].map(parseInt)</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">console</span>.log([<span class=\"number\">10</span>, <span class=\"number\">20</span>, <span class=\"number\">30</span>].map(<span class=\"built_in\">parseInt</span>)) <span class=\"comment\">// [10, NaN, NaN]</span></span><br></pre></td></tr></table></figure></div>\n\n<p>可拆解成:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\">[<span class=\"number\">10</span>, <span class=\"number\">20</span>, <span class=\"number\">30</span>].map(<span class=\"function\">(<span class=\"params\">num, index</span>) =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"built_in\">parseInt</span>(num, index)</span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"10-闭包是什么?\"><a href=\"#10-闭包是什么?\" class=\"headerlink\" title=\"10.闭包是什么?\"></a>10.闭包是什么?</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test1</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">var</span> a = <span class=\"number\">10</span></span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test2</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a)</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">const</span> test3 = test1()</span><br><span class=\"line\">test3()</span><br></pre></td></tr></table></figure></div>\n\n<p>函数内部和外部连接的桥梁,使函数外部可以获取函数内的数据</p>\n<p>闭包使用场景:</p>\n<p><font color=#ff503e><strong>函数</strong></font>作为参数传入,作为返回值为返回</p>\n<p>闭包产生的产生原因:作用域,AO,自由变量查找(函数定义的地方)</p>\n<p>闭包缺点:变量会常驻内存,得不到释放</p>\n<h1 id=\"11-事件代理\"><a href=\"#11-事件代理\" class=\"headerlink\" title=\"11.事件代理\"></a>11.事件代理</h1><iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/fnIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h1 id=\"12-阻止事件冒泡和默认行为\"><a href=\"#12-阻止事件冒泡和默认行为\" class=\"headerlink\" title=\"12.阻止事件冒泡和默认行为\"></a>12.阻止事件冒泡和默认行为</h1><p>event.stopPropagation()<br>event.preventDefault()</p>\n<hr>\n<h1 id=\"13-减少DOM操作\"><a href=\"#13-减少DOM操作\" class=\"headerlink\" title=\"13.减少DOM操作\"></a>13.减少DOM操作</h1><p>缓存DOM结果<br>将多次DOM操作合并到一次插入</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><body></span><br><span class=\"line\"> <ul id=<span class=\"string\">"list"</span>></ul></span><br><span class=\"line\"></body></span><br><span class=\"line\"><script></span><br><span class=\"line\"> <span class=\"keyword\">const</span> list = <span class=\"built_in\">document</span>.getElementById(<span class=\"string\">'list'</span>)</span><br><span class=\"line\"> <span class=\"keyword\">const</span> frag = <span class=\"built_in\">document</span>.createDocumentFragment()</span><br><span class=\"line\"> <span class=\"keyword\">for</span>(<span class=\"keyword\">let</span> i = <span class=\"number\">0</span>; i < <span class=\"number\">1000</span>; i++) {</span><br><span class=\"line\"> <span class=\"keyword\">const</span> li = <span class=\"built_in\">document</span>.createElement(<span class=\"string\">'li'</span>)</span><br><span class=\"line\"> li.innerHTML = <span class=\"string\">`list <span class=\"subst\">${i}</span>`</span></span><br><span class=\"line\"> <span class=\"comment\">// 大量DOM操作影响性能</span></span><br><span class=\"line\"> <span class=\"comment\">// list.appendChild(li)</span></span><br><span class=\"line\"> <span class=\"comment\">// frag不涉及DOM操作,不影响性能</span></span><br><span class=\"line\"> frag.appendChild(li)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"comment\">// 一次性插入</span></span><br><span class=\"line\"> list.appendChild(frag)</span><br><span class=\"line\"></script></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"14-和-的区别\"><a href=\"#14-和-的区别\" class=\"headerlink\" title=\"14.== 和 === 的区别\"></a>14.== 和 === 的区别</h1><p>== 会尽可能使两边相等,会使用类型转换</p>\n<p>除了 == null 都是用 ===</p>\n<hr>\n<h1 id=\"15-函数声明和函数表达式的区别\"><a href=\"#15-函数声明和函数表达式的区别\" class=\"headerlink\" title=\"15.函数声明和函数表达式的区别\"></a>15.函数声明和函数表达式的区别</h1><p>函数声明 function fn() {}<br>函数表达式 const fn = function fn() {}</p>\n<p>函数声明会在代码执行前预加载,函数表达式不会</p>\n<hr>\n<h1 id=\"16-new-Object-和Object-create-的区别\"><a href=\"#16-new-Object-和Object-create-的区别\" class=\"headerlink\" title=\"16.new Object()和Object.create()的区别\"></a>16.new Object()和Object.create()的区别</h1><p>{}等于new Object(),原型是Object.prototype<br>Object.create()创建的对象没有原型,没有原型,可指定原型</p>\n<hr>\n<h1 id=\"17-正则-字符串字母开头,后面字母数字下划线,长度6-30\"><a href=\"#17-正则-字符串字母开头,后面字母数字下划线,长度6-30\" class=\"headerlink\" title=\"17.正则:字符串字母开头,后面字母数字下划线,长度6-30\"></a>17.正则:字符串字母开头,后面字母数字下划线,长度6-30</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> reg = \\^[a-zA-Z]\\w{<span class=\"number\">5</span>,<span class=\"number\">29</span>}$\\</span><br></pre></td></tr></table></figure></div>\n\n<p><a href=\"https://deerchao.cn/tutorials/regex/regex.htm\">正则表达式30分钟入门教程</a></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 邮政编码</span></span><br><span class=\"line\">/\\d{<span class=\"number\">6</span>}/</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"comment\">// 小写英文字母 (+ 一次到多次)</span></span><br><span class=\"line\">/^[a-z]+$/</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"comment\">// 英文字母</span></span><br><span class=\"line\">/^[a-zA-Z]+$/</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"comment\">// 日期格式 XXXX/XX/XX</span></span><br><span class=\"line\">/^\\d{<span class=\"number\">4</span>}-\\d{<span class=\"number\">1</span>,<span class=\"number\">2</span>}-\\d{<span class=\"number\">1</span>,<span class=\"number\">2</span>}$/</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"comment\">// 用户名 6-18位</span></span><br><span class=\"line\">/^[a-zA-Z]\\w{<span class=\"number\">5</span>, <span class=\"number\">17</span>}/</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"comment\">// 简单的IP地址匹配 转义字符</span></span><br><span class=\"line\">/\\d+\\.\\d+\\.\\d+\\.\\d+/</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"18-获取多个数字中的最大值\"><a href=\"#18-获取多个数字中的最大值\" class=\"headerlink\" title=\"18.获取多个数字中的最大值\"></a>18.获取多个数字中的最大值</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">max</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">const</span> nums = <span class=\"built_in\">Array</span>.prototype.slice.call(<span class=\"built_in\">arguments</span>)</span><br><span class=\"line\"> <span class=\"keyword\">let</span> max = <span class=\"number\">0</span>;</span><br><span class=\"line\"> nums.forEach(<span class=\"function\"><span class=\"params\">n</span> =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (n > max) {</span><br><span class=\"line\"> max = n</span><br><span class=\"line\"> }</span><br><span class=\"line\"> })</span><br><span class=\"line\"> <span class=\"keyword\">return</span> max</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(max(<span class=\"number\">1</span>, <span class=\"number\">100</span>, <span class=\"number\">20</span>, <span class=\"number\">50</span>, <span class=\"number\">6</span>, <span class=\"number\">12</span>))</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript","面试"]},{"title":"JavaScript基础02-面向对象编程","url":"/2020/12/08/JavaScript%E5%9F%BA%E7%A1%8002-%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%BC%96%E7%A8%8B/","content":"<p>JavaScript具有很强的面向对象编程能力,本文主要整理关于JavaScript的面向对象编程的基础知识。</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-实例对象\"><a href=\"#1-实例对象\" class=\"headerlink\" title=\"1.实例对象\"></a>1.实例对象</h1><h2 id=\"1-1-什么是对象?\"><a href=\"#1-1-什么是对象?\" class=\"headerlink\" title=\"1.1.什么是对象?\"></a>1.1.什么是对象?</h2><p>在了解对象之前,我们首先要了解什么是面向对象编程(OOP)。面向对象编程是现在的主流编程范式,它将真实世界各种复杂的关系,抽象成了一个个对象,然后由对象之间分工协作,完成对真实世界的模拟。每个对象都是功能中心,分工明确,对象可复用,可通过继承机制来定制。因此,面向对象编程具有灵活,代码可复用,高度模块化等特点,容易维护和开发。</p>\n<p>那么什么是对象?我们从两方面来理解。</p>\n<hr>\n<h3 id=\"1-1-1-对象是单个实物的抽象\"><a href=\"#1-1-1-对象是单个实物的抽象\" class=\"headerlink\" title=\"1.1.1.对象是单个实物的抽象\"></a>1.1.1.对象是单个实物的抽象</h3><p>一个人,一本书,一个页面,一个数据库都可以是对象,当实物抽象成对象后,实物之间的关系就变成了对象之间的关系,就可以通过模拟现实情况,针对对象进行编程。</p>\n<h3 id=\"1-1-2-对象是一个容器,封装了属性-property-和方法-method\"><a href=\"#1-1-2-对象是一个容器,封装了属性-property-和方法-method\" class=\"headerlink\" title=\"1.1.2.对象是一个容器,封装了属性(property)和方法(method)\"></a>1.1.2.对象是一个容器,封装了属性(property)和方法(method)</h3><p>属性是对象的状态,方法是对象的行为。比如,我们可以把猫抽象成animal对象,使用属性记录具体是哪种动物,使用方法表示动物的某种行为(睡觉,奔跑,捕猎等)。</p>\n<hr>\n<h2 id=\"1-2-构造函数\"><a href=\"#1-2-构造函数\" class=\"headerlink\" title=\"1.2.构造函数\"></a>1.2.构造函数</h2><p>面向对象编程的第一步,就是要生成对象。对象是单个实物的抽象。通常需要一个模版来表示某一类实物的共同特征,然后对象根据这个模版生成。典型的面向对象编程语言(C++,JAVA),都有类(class)的概念,所谓的类就是对象的模版,对象就是类的实例。但是,在js中的对象,不是基于类的,而是基于构造函数(constructor)和原型链(prototype)。</p>\n<p>js使用构造函数来作为对象的模版。构造函数是专门用来生成实例对象的函数,它是对象的模版,描述实例对象的基本结构。一个构造函数,可以生成多个实例对象,这些实例对象都有相同的结构。</p>\n<p>构造函数就是一个普通函数,但是具有自己的特征和用法:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> Vehicle = <span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.price = <span class=\"number\">1000</span>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>上面代码中,Vehicle就是构造函数。为了与普通函数区分,构造函数的首字母要大写。</p>\n<p>构造函数有两个特点:</p>\n<ul>\n<li>函数内部使用this关键字,代表要生成的对象实例</li>\n<li>生成对象的时候,必须使用new关键字</li>\n</ul>\n<hr>\n<h1 id=\"2-new命令\"><a href=\"#2-new命令\" class=\"headerlink\" title=\"2.new命令\"></a>2.new命令</h1><h2 id=\"2-1-基本用法\"><a href=\"#2-1-基本用法\" class=\"headerlink\" title=\"2.1.基本用法\"></a>2.1.基本用法</h2><p>new命令的作用,就是执行构造函数,返回一个实例对象。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> Vehicle = <span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.price = <span class=\"number\">1000</span>;</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">var</span> v = <span class=\"keyword\">new</span> Vehicle();</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(v.price) <span class=\"comment\">// 1000</span></span><br></pre></td></tr></table></figure></div>\n\n<p>上述代码中,我们通过new命令,可以让构造函数Vehicle生成一个实例对象,保存在变量v中,这个实例对象从构造函数Vehicle中获得了price属性:在new命令执行的同时,构造函数内部的this指向了新生成的实例对象,this.price就代表实例对象有一个price属性,值为1000。</p>\n<p>构造函数仍然具有函数的特征,需要的时候,构造函数可可以接收参数:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> Vehicle = <span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\">p</span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.price = p;</span><br><span class=\"line\">};</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">var</span> v = <span class=\"keyword\">new</span> Vehicle(<span class=\"number\">500</span>);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(v.price) <span class=\"comment\">// 500</span></span><br></pre></td></tr></table></figure></div>\n\n<blockquote>\n<p>注意:new命令本身就是执行构造函数,所以构造函数可以不加括号,但为了突出是函数调用,还是推荐使用括号。</p>\n</blockquote>\n<p>那么,我们不妨猜想一下,如果忘了使用new命令,直接调用构造函数会发生什么?</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> Vehicle = <span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.price = <span class=\"number\">1000</span>;</span><br><span class=\"line\">};</span><br><span class=\"line\"><span class=\"keyword\">var</span> v = Vehicle();</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(v) <span class=\"comment\">// undefined</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(price) <span class=\"comment\">// 1000</span></span><br></pre></td></tr></table></figure></div>\n\n<p>这种情况下,Vehicle变成了普通函数,并不会生成实例对象,变量v的值变成了undefined,而且price属性指向window,变成了全局变量,具体原因在后面this章节会详细解释。通过这段代码,我们要注意避免不使用new命令,直接调用构造函数的操作。</p>\n<hr>\n<h2 id=\"2-2-安全的使用new命令\"><a href=\"#2-2-安全的使用new命令\" class=\"headerlink\" title=\"2.2.安全的使用new命令\"></a>2.2.安全的使用new命令</h2><p>为了保证所有的构造函数必须与new命令一起使用,我们可以使用以下两种方式:</p>\n<p>1.在构造函数内部使用严格模式:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> Vehicle = <span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"><span class=\"meta\"> 'use strict'</span>; </span><br><span class=\"line\"> <span class=\"built_in\">this</span>.price = <span class=\"number\">1000</span>;</span><br><span class=\"line\">};</span><br><span class=\"line\"><span class=\"keyword\">var</span> v = Vehicle();</span><br><span class=\"line\"><span class=\"comment\">// Uncaught TypeError: Cannot set property 'price' of undefined</span></span><br></pre></td></tr></table></figure></div>\n\n<p>js不允许对undefined添加属性,在严格模式中,函数内部的this不能指向全局对象,默认值为undefined,所以如果不加new调用构造函数会报错。</p>\n<p>2.在函数内部判断是否使用new命令,如果没有,返回一个实例对象:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> Vehicle = <span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span>(! (<span class=\"built_in\">this</span> <span class=\"keyword\">instanceof</span> Vehicle)) {</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"keyword\">new</span> Vehicle()</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.price = <span class=\"number\">1000</span>;</span><br><span class=\"line\">};</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(Vehicle().price) <span class=\"comment\">// 1000</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"keyword\">new</span> Vehicle().price) <span class=\"comment\">// 1000</span></span><br></pre></td></tr></table></figure></div>\n\n<p>上面代码中的构造函数,不管是否使用new命令,都会得到相同结果。</p>\n<hr>\n<h2 id=\"2-3-new命令原理\"><a href=\"#2-3-new命令原理\" class=\"headerlink\" title=\"2.3.new命令原理\"></a>2.3.new命令原理</h2><p>使用new命令时,对后面的函数执行了一下过程:</p>\n<ul>\n<li>创建一个空对象,作为要返回的对象实例</li>\n<li>将空对象的原型指向构造函数的属性</li>\n<li>将空对象赋值给构造函数内部this</li>\n<li>执行构造函数内部代码</li>\n</ul>\n<p>构造函数内部,this指向一个新生成的空对象,所有针对this的操作,都会作用到这个空对象上。构造函数之所以叫“构造”函数,就是操作一个空对象(this对象),将其“构造”成需要的样子。</p>\n<p>如果在构造函数内部有return语句,而且return后跟着一个对象,那么new命令会返回return指定的对象,否则,忽略return语句,直接返回this对象:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> Vehicle = <span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.price = <span class=\"number\">1000</span>;</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"number\">2000</span>;</span><br><span class=\"line\">};</span><br><span class=\"line\"><span class=\"keyword\">var</span> v = <span class=\"keyword\">new</span> Vehicle();</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(v.price); <span class=\"comment\">// 1000</span></span><br></pre></td></tr></table></figure></div>\n\n<p>上述代码中,构造函数Vehicle返回了一个数值,new命令会忽略return,返回this对象。</p>\n<p>但是,如果return返回的是一个与this无关的新对象,那么new命令会返回新对象而不是this对象:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> Vehicle = <span class=\"function\"><span class=\"keyword\">function</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">this</span>.price = <span class=\"number\">1000</span>;</span><br><span class=\"line\"> <span class=\"keyword\">return</span> { <span class=\"attr\">price</span>: <span class=\"number\">2000</span> };</span><br><span class=\"line\">};</span><br><span class=\"line\"><span class=\"keyword\">var</span> v = <span class=\"keyword\">new</span> Vehicle();</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(v.price); <span class=\"comment\">// 2000</span></span><br></pre></td></tr></table></figure></div>\n\n<p>如果对普通函数(内部没有this关键字的函数)使用new命令,则会返回一个空对象。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">getMessage</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"string\">'this is a message'</span>;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">var</span> msg = <span class=\"keyword\">new</span> getMessage();</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(msg); <span class=\"comment\">// {}}</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"keyword\">typeof</span> msg); <span class=\"comment\">// object</span></span><br></pre></td></tr></table></figure></div>\n\n<p>上述代码中,getMessage是一个普通函数,返回一个字符串。对它使用new命令,会得到一个空对象。</p>\n<hr>\n<h2 id=\"2-4-new命令的内部过程\"><a href=\"#2-4-new命令的内部过程\" class=\"headerlink\" title=\"2.4.new命令的内部过程\"></a>2.4.new命令的内部过程</h2><p>new命令的执行过程主要分为4个部分:</p>\n<ul>\n<li>1.创建一个空对象</li>\n<li>2.链接到原型</li>\n<li>3.绑定this</li>\n<li>4.返回新对象</li>\n</ul>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// function Person(name, age) {</span></span><br><span class=\"line\"><span class=\"comment\">// this.name = name;</span></span><br><span class=\"line\"><span class=\"comment\">// this.age = age;</span></span><br><span class=\"line\"><span class=\"comment\">// }</span></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">myNew</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">let</span> obj = {};</span><br><span class=\"line\"> <span class=\"comment\">// 将arguments类数组转化为数组args</span></span><br><span class=\"line\"> <span class=\"keyword\">let</span> args = [].slice.call(<span class=\"built_in\">arguments</span>);</span><br><span class=\"line\"> <span class=\"comment\">// 将args数组的第一个值作为构造函数</span></span><br><span class=\"line\"> <span class=\"keyword\">let</span> Con = args.shift();</span><br><span class=\"line\"> obj.__proto__ = Con.prototype;</span><br><span class=\"line\"> <span class=\"keyword\">let</span> res = Con.apply(obj, args);</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"keyword\">typeof</span> res === <span class=\"string\">'object'</span> ? res : obj;</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"comment\">// var p = myNew(Person, 'CalDey', 23)</span></span><br><span class=\"line\"><span class=\"comment\">// console.log(p);</span></span><br></pre></td></tr></table></figure></div>\n\n<p>想要更加深入了解new的执行过程,可以参考Blog中这篇文章:<a href=\"/2020/12/09/JavaScript-%E6%B5%85%E6%9E%90new%E5%91%BD%E4%BB%A4%E7%9A%84%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B/\" title=\"JavaScript-浅析new命令的执行过程\">JavaScript-浅析new命令的执行过程</a></p>\n<hr>\n<h2 id=\"2-5-new-target\"><a href=\"#2-5-new-target\" class=\"headerlink\" title=\"2.5.new.target\"></a>2.5.new.target</h2><p>函数内部可使用new.target判断当前函数是否由new调用,如果是new调用,new.target指向当前函数,否则返回undefined。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">f</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"keyword\">new</span>.target === f);</span><br><span class=\"line\">}</span><br><span class=\"line\">f(); <span class=\"comment\">// false</span></span><br><span class=\"line\"><span class=\"keyword\">new</span> f(); <span class=\"comment\">//true</span></span><br></pre></td></tr></table></figure></div>\n\n<p>我们也可以通过这个属性,判断函数调用是否使用了new命令:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">f</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">if</span> (! <span class=\"keyword\">new</span>.target)</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"keyword\">new</span> <span class=\"built_in\">Error</span>(<span class=\"string\">'请使用new命令!'</span>)</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(f()) <span class=\"comment\">// Error: 请使用new命令!</span></span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"2-6-通过Object-create-创建实例对象\"><a href=\"#2-6-通过Object-create-创建实例对象\" class=\"headerlink\" title=\"2.6.通过Object.create()创建实例对象\"></a>2.6.通过Object.create()创建实例对象</h2><p>构造函数作为模板,可以生成实例对象。但有时我们不能拿到构造函数,只能获取一个已有的对象。我们希望能够以这个已有的对象作为模板,生成实例对象,这时我们可以使用Object.create()方法:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> person1 = {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span>,</span><br><span class=\"line\"> age: <span class=\"string\">'23'</span>,</span><br><span class=\"line\"> sayHi: <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'Hi,'</span> + <span class=\"built_in\">this</span>.name + <span class=\"string\">',Nice to meet you'</span>);</span><br><span class=\"line\"> }</span><br><span class=\"line\">};</span><br><span class=\"line\"></span><br><span class=\"line\">person2 = <span class=\"built_in\">Object</span>.create(person1);</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(person2.name,person2.age); <span class=\"comment\">// CalDey, 23</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(person2.sayHi()); <span class=\"comment\">// Hi,CalDey,Nice to meet you</span></span><br></pre></td></tr></table></figure></div>\n\n<p>上面代码中,person1是person2的模板,后者继承了前者的属性和方法。</p>\n<hr>\n<h1 id=\"3-this关键字\"><a href=\"#3-this关键字\" class=\"headerlink\" title=\"3.this关键字\"></a>3.this关键字</h1><h2 id=\"3-1-this指向\"><a href=\"#3-1-this指向\" class=\"headerlink\" title=\"3.1.this指向\"></a>3.1.this指向</h2><p>this关键字是js中非常重要的语法点,我们在上文中已经知道了this可以用在构造函数中,表示实例对象。除此以外,this还可以用在其他场合,但不管什么场合,this总是会返回一个对象。</p>\n<p>简单来说,当前属性和方法在哪个对象上,this就指向哪个对象:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> person = {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span>,</span><br><span class=\"line\"> message: <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'Hi,'</span> + <span class=\"built_in\">this</span>.name)</span><br><span class=\"line\"> }</span><br><span class=\"line\">};</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(person.message()) <span class=\"comment\">// Hi,CalDey</span></span><br></pre></td></tr></table></figure></div>\n\n<p>这段代码中this指向name属性所在的对象,this.name是在message方法中调用的,而message方法处在person对象上,因此this指向person,this.name等价于person.name。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> person1 = {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span>,</span><br><span class=\"line\"> message: <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'Hi,'</span> + <span class=\"built_in\">this</span>.name)</span><br><span class=\"line\"> }</span><br><span class=\"line\">};</span><br><span class=\"line\"><span class=\"keyword\">var</span> person2 = {</span><br><span class=\"line\"> name: <span class=\"string\">'Tom'</span></span><br><span class=\"line\">};</span><br><span class=\"line\">person2.message = person1.message;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(person2.message()) <span class=\"comment\">// Hi.Tom</span></span><br></pre></td></tr></table></figure></div>\n\n<p>我们将person1的message属性赋给person2,于是person2.message代表message方法当前所在的对象是person2,所以this.message等价于person2.message。</p>\n<p>我们将this.name单独取出来封装成函数,这样能够更加清楚的看出this指向的变化:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">f</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"built_in\">this</span>.name;</span><br><span class=\"line\">};</span><br><span class=\"line\"><span class=\"keyword\">var</span> p1 = {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span>,</span><br><span class=\"line\"> message: f</span><br><span class=\"line\">};</span><br><span class=\"line\"><span class=\"keyword\">var</span> p2 = {</span><br><span class=\"line\"> name: <span class=\"string\">'Tom'</span>,</span><br><span class=\"line\"> message: f</span><br><span class=\"line\">};</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(p1.message()); <span class=\"comment\">// CalDey</span></span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(p2.message()); <span class=\"comment\">// Tom</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">var</span> p = {</span><br><span class=\"line\"> name: <span class=\"string\">'CalDey'</span>,</span><br><span class=\"line\"> message: <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </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><br><span class=\"line\"><span class=\"keyword\">var</span> name = <span class=\"string\">'Tom'</span>;</span><br><span class=\"line\"><span class=\"keyword\">var</span> f = p.message;</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(f()) <span class=\"comment\">// Tom</span></span><br></pre></td></tr></table></figure></div>\n\n<p>p.message被赋给变量f,this指向f所在的对象(这里指向顶层对象)。可以看出,只要函数被赋给另一个变量,this指向就会改变。</p>\n<p>下面是一个web编程实例:</p>\n<iframe width=\"100%\" height=\"200\" src=\"//jsrun.net/TyIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>每当用户向文本框输入一个值,就会通过onChange调用回调函数,浏览器向回调函数传入当前对象,this指向当前对象,即文本框,this.value获取用户输入值。</p>\n<p>通过上述实例我们可以看出,this的指向是动态的。</p>\n<hr>\n<p>未完待续</p>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"JavaScript进阶02-作用域链和闭包原理","url":"/2021/02/19/JavaScript%E8%BF%9B%E9%98%B602-%E4%BD%9C%E7%94%A8%E5%9F%9F%E9%93%BE%E5%92%8C%E9%97%AD%E5%8C%85%E5%8E%9F%E7%90%86/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-作用域和作用域链\"><a href=\"#1-作用域和作用域链\" class=\"headerlink\" title=\"1.作用域和作用域链\"></a>1.作用域和作用域链</h1><p>在函数被创建时,会自动生成一个隐式属性[[scope]],它是存储作用域链的容器。js代码在执行前会生成GO,即全局作用域,当函数执行时生成一个局部作用域AO,用来临时存储函数内部变量,在函数执行完毕后该AO被销毁</p>\n<p>每当一个函数被执行就创建一个新的AO,该函数中变量的值首先从自己的AO中寻找,如果未找到,向上一个作用域查找,仍未找到,继续向上一级查找,最终在全局作用域GO查找,这个过程就是作用域链</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">a</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">b</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">var</span> b = <span class=\"number\">2</span>;</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">var</span> a = <span class=\"number\">1</span>;</span><br><span class=\"line\"> b();</span><br><span class=\"line\"></span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(b);</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">var</span> c = <span class=\"number\">3</span>;</span><br><span class=\"line\">a();</span><br></pre></td></tr></table></figure></div>\n\n<p>因此可以很好的理解为什么这段代码中变量b的值不是2</p>\n<p>输出语句在函数a中执行,函数a自己的AO中没有变量b,会向上级作用域查找,即GO,a的作用域链中没有b的AO,因此找不到b=2</p>\n<hr>\n<h1 id=\"2-函数从创建到执行后销毁的过程\"><a href=\"#2-函数从创建到执行后销毁的过程\" class=\"headerlink\" title=\"2.函数从创建到执行后销毁的过程\"></a>2.函数从创建到执行后销毁的过程</h1><p>1.函数声明</p>\n<ul>\n<li>[[scope]] 生成存储作用域链的容器</li>\n<li>scope chain 作用域链</li>\n<li>GO 作用域链默认第0位存储全局作用域GO</li>\n</ul>\n<p>2.函数执行</p>\n<ul>\n<li>AO 函数执行时生成自己的局部作用域AO</li>\n<li>该AO传入作用域链中第0位存储,GO变成第1位</li>\n</ul>\n<p>3.函数执行完毕</p>\n<ul>\n<li>销毁自己的AO</li>\n<li>作用域链中第0位AO被销毁,GO再次变成第0位</li>\n</ul>\n<hr>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">a</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">b</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">c</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> }</span><br><span class=\"line\"> c();</span><br><span class=\"line\"> }</span><br><span class=\"line\"> b();</span><br><span class=\"line\">}</span><br><span class=\"line\">a();</span><br></pre></td></tr></table></figure></div>\n\n<p>当函数中包含其他函数时,当函数a执行时,函数b被定义,b处于a的环境下,b的作用域链和a的作用域链相同。当b执行时,b生成自己的AO,传入scope chain中第0位,a的AO变为第1位</p>\n<p>完整过程如下:</p>\n<details>\n <summary>点击展开</summary>\n <div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"number\">1.</span>a定义:a.[[scope]] -> <span class=\"number\">0</span>:GO</span><br><span class=\"line\"><span class=\"number\">2.</span>a执行:a.[[scope]] -> <span class=\"number\">0</span>:AO(a) <span class=\"number\">1</span>:GO 同时,b定义:b.[[scope]] = a.[[scope]]</span><br><span class=\"line\"><span class=\"number\">3.</span>b执行:b.[[scope]] -> <span class=\"number\">0</span>:AO(b) <span class=\"number\">1</span>:AO(a) <span class=\"number\">2</span>:GO 同时,c定义:c.[[scope]] = b.[[scope]]</span><br><span class=\"line\"><span class=\"number\">4.</span>c执行:c.[[scope]] -> <span class=\"number\">0</span>:AO(c) <span class=\"number\">1</span>:AO(b) <span class=\"number\">2</span>:AO(a) <span class=\"number\">3</span>:GO 同时,c定义:c.[[scope]] = b.[[scope]]</span><br><span class=\"line\"><span class=\"number\">5.</span>c结束:c.[[scope]] -> <span class=\"number\">0</span>:AO(b) <span class=\"number\">1</span>:AO(a) <span class=\"number\">2</span>:GO</span><br><span class=\"line\"><span class=\"number\">6.</span>b结束:b.[[scope]] -> <span class=\"number\">0</span>:AO(a) <span class=\"number\">1</span>:GO 同时 c.[[scope]] X</span><br><span class=\"line\"><span class=\"number\">7.</span>a结束:a.[[scope]] -> <span class=\"number\">0</span>:GO 同时 b.[[scope]] X</span><br><span class=\"line\">外层函数a的AO中包含内层函数本身,当外层函数a执行完成后a的AO被删除,内层函数也会被一并删除,因此内层函数的作用域链也就不存在了 </span><br></pre></td></tr></table></figure></div>\n</details>\n\n<hr>\n<h1 id=\"3-闭包的本质\"><a href=\"#3-闭包的本质\" class=\"headerlink\" title=\"3.闭包的本质\"></a>3.闭包的本质</h1><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test1</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test2</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">var</span> b = <span class=\"number\">2</span>;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a);</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">var</span> a = <span class=\"number\">1</span>;</span><br><span class=\"line\"> <span class=\"keyword\">return</span> test2;</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">var</span> test3 = test1();</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(test3);</span><br><span class=\"line\">test3();</span><br></pre></td></tr></table></figure></div>\n\n<p>当test1执行完成后,test1的AO本应该被销毁,test2的作用域链也应该一并被销毁。但此时test1中的test2被抛到函数外部,且被全局变量test3接收,此时test3的值为test2函数。执行test3,即执行test2函数,test2生成自己的AO作为作用域链第0位,test1的AO变为第1位。test3执行完毕后销毁,test2的AO被销毁,但test1的AO仍然存在,未被销毁,因此仍然能够通过作用域链向上查找,访问test1的AO中的变量a值</p>\n<p>当内部函数被返回到外部并保存时,一定会产生闭包,闭包不释放原来的作用域链,过度闭包可能会导致内存泄漏,引起加载变慢</p>\n<hr>\n<h1 id=\"4-自由变量\"><a href=\"#4-自由变量\" class=\"headerlink\" title=\"4.自由变量\"></a>4.自由变量</h1><p>一个变量在当前作用域未被定义,但被使用了<br>向上级作用域AO查找,一层层依次直到全局<br>如果全局作用域GO也没有找到,返回报错信息 xx is not defined</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">let</span> a = <span class=\"number\">0</span></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">fn1</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">let</span> a1 = <span class=\"number\">100</span></span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">fn2</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">let</span> a2 = <span class=\"number\">200</span></span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">fn3</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">let</span> a3 = <span class=\"number\">300</span></span><br><span class=\"line\"> <span class=\"keyword\">return</span> a + a1 + a2 + a3</span><br><span class=\"line\"> }</span><br><span class=\"line\"> fn3()</span><br><span class=\"line\"> }</span><br><span class=\"line\"> fn2()</span><br><span class=\"line\">}</span><br><span class=\"line\">fn1()</span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">create</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">let</span> a = <span class=\"number\">100</span></span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a)</span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">let</span> fn = create()</span><br><span class=\"line\"><span class=\"keyword\">let</span> a = <span class=\"number\">200</span></span><br><span class=\"line\">fn() <span class=\"comment\">// 100</span></span><br></pre></td></tr></table></figure></div>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">print</span>(<span class=\"params\">fn</span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">const</span> a = <span class=\"number\">200</span></span><br><span class=\"line\"> fn() <span class=\"comment\">// 100</span></span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">const</span> a = <span class=\"number\">100</span></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">fn</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(a)</span><br><span class=\"line\">}</span><br><span class=\"line\">print(fn) <span class=\"comment\">// 100</span></span><br></pre></td></tr></table></figure></div>\n\n<blockquote>\n<p>自由变量的查找,取决于函数被定义的位置,而非函数执行位置</p>\n</blockquote>\n<h1 id=\"4-闭包应用\"><a href=\"#4-闭包应用\" class=\"headerlink\" title=\"4.闭包应用\"></a>4.闭包应用</h1><p>1.寄存器</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">test</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">var</span> n = <span class=\"number\">100</span></span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">add</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> n++;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(n)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">reduce</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> n--;</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(n)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> [add, reduce]</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"keyword\">var</span> num = test()</span><br><span class=\"line\">num[<span class=\"number\">1</span>](); <span class=\"comment\">// 99</span></span><br><span class=\"line\">num[<span class=\"number\">1</span>](); <span class=\"comment\">// 98</span></span><br><span class=\"line\">num[<span class=\"number\">1</span>](); <span class=\"comment\">// 97</span></span><br><span class=\"line\">num[<span class=\"number\">0</span>](); <span class=\"comment\">// 98</span></span><br><span class=\"line\">num[<span class=\"number\">0</span>](); <span class=\"comment\">// 99</span></span><br><span class=\"line\">num[<span class=\"number\">0</span>](); <span class=\"comment\">// 100</span></span><br></pre></td></tr></table></figure></div>\n\n<p>2.对象闭包</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">cat</span> (<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"keyword\">var</span> action = <span class=\"string\">''</span></span><br><span class=\"line\"> <span class=\"comment\">// 通过对象闭包</span></span><br><span class=\"line\"> <span class=\"keyword\">var</span> operation = {</span><br><span class=\"line\"> setAction: <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">thing</span>) </span>{</span><br><span class=\"line\"> action = thing;</span><br><span class=\"line\"> },</span><br><span class=\"line\"> show: <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">'Cat like '</span> + action)</span><br><span class=\"line\"> }</span><br><span class=\"line\"> }</span><br><span class=\"line\"> <span class=\"keyword\">return</span> operation</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">var</span> cat = cat();</span><br><span class=\"line\">cat.setAction(<span class=\"string\">'eat meat'</span>);</span><br><span class=\"line\">cat.show()</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript","JavaScript进阶"]},{"title":"Vue-变化的文本","url":"/2021/01/12/Vue-%E5%8F%98%E5%8C%96%E7%9A%84%E6%96%87%E6%9C%AC/","content":"<p>通过Vue实现文本自动更新</p>\n<hr>\n<a id=\"more\"></a>\n\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/p4IKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n","categories":["Vue"],"tags":["Vue"]},{"title":"Vue-基本语法","url":"/2021/01/12/Vue-%E5%9F%BA%E6%9C%AC%E8%AF%AD%E6%B3%95/","content":"<p>通过代码快速入门Vue基础语法</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-模版语法\"><a href=\"#1-模版语法\" class=\"headerlink\" title=\"1.模版语法\"></a>1.模版语法</h1><p>插值和指令</p>\n<iframe width=\"100%\" height=\"400\" src=\"//jsrun.net/L4IKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p><a href=\"https://cn.vuejs.org/v2/guide/syntax.html\">详细了解模版语法</a></p>\n<hr>\n<h1 id=\"2-Class与Style绑定\"><a href=\"#2-Class与Style绑定\" class=\"headerlink\" title=\"2.Class与Style绑定\"></a>2.Class与Style绑定</h1><iframe width=\"100%\" height=\"400\" src=\"//jsrun.net/94IKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p><a href=\"https://cn.vuejs.org/v2/guide/class-and-style.html\">详细了解class与style绑定</a></p>\n<hr>\n<h1 id=\"3-条件渲染\"><a href=\"#3-条件渲染\" class=\"headerlink\" title=\"3.条件渲染\"></a>3.条件渲染</h1><p>v-if为惰性渲染,如果初始条件为false,不会渲染该条件块<br>v-show无论什么条件下都会被渲染</p>\n<p>如果需要频繁切换,使用v-show比较好;如果条件很少改变,应使用v-if</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/74IKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p><a href=\"https://cn.vuejs.org/v2/guide/conditional.html\">详细了解条件渲染</a></p>\n<hr>\n<h1 id=\"4-列表渲染\"><a href=\"#4-列表渲染\" class=\"headerlink\" title=\"4.列表渲染\"></a>4.列表渲染</h1><iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/d4IKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p><a href=\"https://cn.vuejs.org/v2/guide/list.html\">详细了解列表渲染</a></p>\n<hr>\n<h1 id=\"5-事件处理\"><a href=\"#5-事件处理\" class=\"headerlink\" title=\"5.事件处理\"></a>5.事件处理</h1><iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/J4IKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p><a href=\"https://cn.vuejs.org/v2/guide/events.html\">详细了解事件处理</a></p>\n<hr>\n<h1 id=\"6-表单输入绑定\"><a href=\"#6-表单输入绑定\" class=\"headerlink\" title=\"6.表单输入绑定\"></a>6.表单输入绑定</h1><iframe width=\"100%\" height=\"400\" src=\"//jsrun.net/m4IKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p><a href=\"https://cn.vuejs.org/v2/guide/forms.html\">详细了解表单输入绑定</a></p>\n<hr>\n<h1 id=\"7-组件基础\"><a href=\"#7-组件基础\" class=\"headerlink\" title=\"7.组件基础\"></a>7.组件基础</h1><p>组件全局注册</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/yKaKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p><a href=\"https://cn.vuejs.org/v2/guide/components.html\">详细了解组件基础</a></p>\n<hr>\n<h1 id=\"8-组件注册\"><a href=\"#8-组件注册\" class=\"headerlink\" title=\"8.组件注册\"></a>8.组件注册</h1><p>组件局部注册</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/IKaKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p><a href=\"https://cn.vuejs.org/v2/guide/components-registration.html\">详细了解组件注册</a></p>\n<hr>\n","categories":["Vue"],"tags":["Vue"]},{"title":"Vue-生命周期","url":"/2021/01/12/Vue-%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/","content":"<p>Vue的生命周期</p>\n<hr>\n<a id=\"more\"></a>\n\n<p><img src=\"https://cn.vuejs.org/images/lifecycle.png\"></p>\n<hr>\n<h1 id=\"Vue的创建过程\"><a href=\"#Vue的创建过程\" class=\"headerlink\" title=\"Vue的创建过程\"></a>Vue的创建过程</h1><iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/k4IKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n","categories":["Vue"],"tags":["Vue"]},{"title":"Vue常见面试题汇总","url":"/2021/02/24/Vue%E5%B8%B8%E8%A7%81%E9%9D%A2%E8%AF%95%E9%A2%98%E6%B1%87%E6%80%BB/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-v-if,v-show的区别?\"><a href=\"#1-v-if,v-show的区别?\" class=\"headerlink\" title=\"1.v-if,v-show的区别?\"></a>1.v-if,v-show的区别?</h1><p>v-if切换会重复创建和删除元素,会重复渲染DOM<br>v-show显示或隐藏元素,变换CSS样式</p>\n<p>何时使用?<br>v-if切换的开销高,v-show渲染的开销高<br>当需要频繁更新数据应使用v-show,反之v-if</p>\n<hr>\n<h1 id=\"2-v-if和v-show为什么不推荐一起使用?\"><a href=\"#2-v-if和v-show为什么不推荐一起使用?\" class=\"headerlink\" title=\"2.v-if和v-show为什么不推荐一起使用?\"></a>2.v-if和v-show为什么不推荐一起使用?</h1><p>v-for优先级高于v-if,先循环后判断</p>\n<p>解决方法:不要把v-if和v-show写在同一个标签上</p>\n<hr>\n<h1 id=\"3-v-for为什么要指定key?\"><a href=\"#3-v-for为什么要指定key?\" class=\"headerlink\" title=\"3.v-for为什么要指定key?\"></a>3.v-for为什么要指定key?</h1><iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/S5aKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>当使用v-for遍历数组时,如果没有指定key,当元素顺序发生变化时,DOM绑定的数据会更新,但顺序不会发生改变,key相当于唯一标识符</p>\n<hr>\n<h1 id=\"4-为什么Vue组件中data必须是一个函数?\"><a href=\"#4-为什么Vue组件中data必须是一个函数?\" class=\"headerlink\" title=\"4.为什么Vue组件中data必须是一个函数?\"></a>4.为什么Vue组件中data必须是一个函数?</h1><p>避免复用组件共享同一份数据</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/QkNKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h1 id=\"5-nextTick\"><a href=\"#5-nextTick\" class=\"headerlink\" title=\"5.$nextTick\"></a>5.$nextTick</h1><p>vue异步渲染,data改变后,DOM不会立即渲染。$nextTick在DOM渲染完成后触发回调,获取最新DOM</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/IkNKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<h1 id=\"4-父子组件传值\"><a href=\"#4-父子组件传值\" class=\"headerlink\" title=\"4.父子组件传值\"></a>4.父子组件传值</h1><p>父组件可以通过props向子组件传递数据,子组件通过$emit向父子件传递数据</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/KDaKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h1 id=\"5-自定义事件\"><a href=\"#5-自定义事件\" class=\"headerlink\" title=\"5.自定义事件\"></a>5.自定义事件</h1><p>1.Event Bus:每个Vue实例都是一个Event Bus,都支持$on/$emit,可以为兄弟组件实例之间new一个Vue实例,作为Event Bus进行通信</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/NraKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>2.Vuex:将状态或方法提取到Vuex,完成共享</p>\n<hr>\n<h1 id=\"6-Vue生命周期\"><a href=\"#6-Vue生命周期\" class=\"headerlink\" title=\"6.Vue生命周期\"></a>6.Vue生命周期</h1><p>①beforeCreate:初始化实例,创建Vue实例后触发的第一个钩子,此时data,methods,computed和watch上的数据和方法都不能被访问</p>\n<p>②created:实例创建完成后发生,当前阶段完成了数据观测,可以使用和更改数据,此时更改数据不会触发updated函数。可以做一些初始数据的获取,在当前阶段无法和DOM进行交互,如果需要,可以通过$nextTick来访问DOM</p>\n<p>③beforeMount:发生在模版渲染到页面之前,template已经导入渲染函数编译,当前阶段虚拟DOM已经创建完成,即将开始渲染,此时可以对数据进行修改,不会触发updated</p>\n<p>④mounted:模版渲染完毕,当前阶段DOM挂载完毕,进行数据双向绑定,可以访问到DOM节点,使用$refs属性可以操作DOM</p>\n<p>⑤beforeUpdate:发生在更新前,也就是响应式数据发生更新,虚拟DOM重新渲染前被触发,可以在此阶段更改数据,不会造成重渲染</p>\n<p>⑥updated:发生在更新完成后,当前阶段DOM已经完成更新,要注意避免在此期间更改数据,可能导致无限循环的更新</p>\n<p>⑦beforeDestroy:发生在实例销毁之前,当前阶段实例完全可以被使用,我们可以在这时进行善后工作,清除计时器,对全局事件解绑</p>\n<p>⑧destoryed:发生在实例销毁之后</p>\n<hr>\n<h1 id=\"7-Vue的响应式系统\"><a href=\"#7-Vue的响应式系统\" class=\"headerlink\" title=\"7.Vue的响应式系统\"></a>7.Vue的响应式系统</h1><p>Vue为MVVM框架,当数据模型data变化时,数据驱动视图更新,这样可以专注于数据本身而非DOM操作</p>\n<p>其原理是Object.defineProperty(Vue3.0为Proxy),利用发布订阅模式,在getter中订阅,setter中发布通知,实现页面实时响应</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/7kNKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h1 id=\"8-computed和watch的区别\"><a href=\"#8-computed和watch的区别\" class=\"headerlink\" title=\"8.computed和watch的区别\"></a>8.computed和watch的区别</h1><p>计算属性computed和监听器watch都可以观察属性变化做出响应</p>\n<p>计算属性可以缓存,将一个或多个data属性经过计算返回一个新值。当依赖属性发生变化时,computed不会立刻重新计算,而是标记成脏数据,当下次computed被获取时,才会重新计算</p>\n<p>watch不具备缓存功能,被监听属性发生变化时,会立即执行该函数</p>\n<hr>\n","categories":["Vue"],"tags":["面试","Vue"]},{"title":"flex布局基础","url":"/2021/01/02/flex%E5%B8%83%E5%B1%80%E5%9F%BA%E7%A1%80/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-什么是flex?\"><a href=\"#1-什么是flex?\" class=\"headerlink\" title=\"1.什么是flex?\"></a>1.什么是flex?</h1><p>传统盒模型在布局时依赖display,position,float等属性,布局繁琐,代码冗长。对于如三栏布局等特殊布局来说非常不方便。flex又称弹性布局,可以为盒模型提供最大程度的灵活性,通过flex可以轻松实现许多复杂布局。、</p>\n<p>任何一个容器都可以指定为 Flex 布局。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.box</span>{</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: flex;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>行内元素也可以使用 Flex 布局。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.box</span>{</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: inline-flex;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>Webkit 内核的浏览器,使用时必须加上-webkit前缀:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.box</span>{</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: -webkit-flex; <span class=\"comment\">/* Safari */</span></span><br><span class=\"line\"> <span class=\"attribute\">display</span>: flex;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h1 id=\"2-基本概念\"><a href=\"#2-基本概念\" class=\"headerlink\" title=\"2.基本概念\"></a>2.基本概念</h1><h2 id=\"容器和项目\"><a href=\"#容器和项目\" class=\"headerlink\" title=\"容器和项目\"></a>容器和项目</h2><p>使用flex的元素被视作flex容器(flex container),其内部所有子元素被称作flex项目(flex item)。</p>\n<p><img src=\"http://www.ruanyifeng.com/blogimg/asset/2015/bg2015071004.png\"></p>\n<p>容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。</p>\n<p>项目默认沿着水平的主轴排列,单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。</p>\n<hr>\n<h1 id=\"3-容器属性\"><a href=\"#3-容器属性\" class=\"headerlink\" title=\"3.容器属性\"></a>3.容器属性</h1><h2 id=\"3-1-flex-direction\"><a href=\"#3-1-flex-direction\" class=\"headerlink\" title=\"3.1.flex-direction\"></a>3.1.flex-direction</h2><p>flex-direction决定主轴的方向</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.box</span> {</span><br><span class=\"line\"> <span class=\"attribute\">flex-direction</span>: row | row-reverse | column | column-reverse;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>它可以设置4个值:</p>\n<ul>\n<li>row(默认值):主轴为水平方向,起点在左端。</li>\n<li>row-reverse:主轴为水平方向,起点在右端。</li>\n<li>column:主轴为垂直方向,起点在上沿。</li>\n<li>column-reverse:主轴为垂直方向,起点在下沿。</li>\n</ul>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/rtIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h2 id=\"3-2-flex-wrap\"><a href=\"#3-2-flex-wrap\" class=\"headerlink\" title=\"3.2.flex-wrap\"></a>3.2.flex-wrap</h2><p>如果一行排不开如何换行?</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.box</span>{</span><br><span class=\"line\"> <span class=\"attribute\">flex-wrap</span>: nowrap | wrap | wrap-reverse;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>它可能取3个值:</p>\n<ul>\n<li>nowrap(默认):不换行。</li>\n<li>wrap:换行,第一行在上方。</li>\n<li>wrap-reverse:换行,第一行在下方。</li>\n</ul>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/AtIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h2 id=\"3-3-flex-flow\"><a href=\"#3-3-flex-flow\" class=\"headerlink\" title=\"3.3.flex-flow\"></a>3.3.flex-flow</h2><p>flex-flow是flex-direction和flex-wrap的简写形式,默认值为row nowrap。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.box</span> {</span><br><span class=\"line\"> <span class=\"attribute\">flex-flow</span>: <flex-direction> || <flex-wrap>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"3-4-justify-content\"><a href=\"#3-4-justify-content\" class=\"headerlink\" title=\"3.4.justify-content\"></a>3.4.justify-content</h2><p>justify-content定义在主轴上的对齐方式</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.box</span> {</span><br><span class=\"line\"> <span class=\"attribute\">justify-content</span>: flex-start | flex-end | center | space-between | space-around;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>它可以取5个值:</p>\n<ul>\n<li>flex-start(默认值):左对齐</li>\n<li>flex-end:右对齐</li>\n<li>center: 居中</li>\n<li>space-between:两端对齐,项目之间的间隔都相等。</li>\n<li>space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。</li>\n</ul>\n<iframe width=\"100%\" height=\"480\" src=\"//jsrun.net/RtIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h2 id=\"3-5-align-item\"><a href=\"#3-5-align-item\" class=\"headerlink\" title=\"3.5.align-item\"></a>3.5.align-item</h2><p>align-item定义在交叉轴上的对齐方式</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.box</span> {</span><br><span class=\"line\"> <span class=\"attribute\">align-items</span>: flex-start | flex-end | center | baseline | stretch;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>它可以取5个值:</p>\n<ul>\n<li>flex-start:交叉轴的起点对齐。</li>\n<li>flex-end:交叉轴的终点对齐。</li>\n<li>center:交叉轴的中点对齐。</li>\n<li>baseline: 项目的第一行文字的基线对齐。</li>\n<li>stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。</li>\n</ul>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/MtIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/StIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h2 id=\"3-6-align-content\"><a href=\"#3-6-align-content\" class=\"headerlink\" title=\"3.6.align-content\"></a>3.6.align-content</h2><p>align-content定义了多根轴线的对齐方式,如果轴线只有一条,该属性无效</p>\n<p>它可以取6个值:</p>\n<ul>\n<li>flex-start:与交叉轴的起点对齐。</li>\n<li>flex-end:与交叉轴的终点对齐。</li>\n<li>center:与交叉轴的中点对齐。</li>\n<li>space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。</li>\n<li>space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。</li>\n<li>stretch(默认值):轴线占满整个交叉轴。</li>\n</ul>\n<p><img src=\"http://www.ruanyifeng.com/blogimg/asset/2015/bg2015071012.png\"></p>\n<hr>\n<h1 id=\"4-项目属性\"><a href=\"#4-项目属性\" class=\"headerlink\" title=\"4.项目属性\"></a>4.项目属性</h1><h2 id=\"4-1-order\"><a href=\"#4-1-order\" class=\"headerlink\" title=\"4.1.order\"></a>4.1.order</h2><p>order属性定义项目的排序顺序,值越小排得越靠前,默认为0</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item</span> {</span><br><span class=\"line\"> <span class=\"attribute\">order</span>: <integer>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/4tIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h2 id=\"4-2-flex-grow\"><a href=\"#4-2-flex-grow\" class=\"headerlink\" title=\"4.2.flex-grow\"></a>4.2.flex-grow</h2><p>flex-grow定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item</span> {</span><br><span class=\"line\"> <span class=\"attribute\">flex-grow</span>: <number>; <span class=\"comment\">/* default 0 */</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/KnIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。</p>\n<hr>\n<h2 id=\"4-3-flex-shrink\"><a href=\"#4-3-flex-shrink\" class=\"headerlink\" title=\"4.3.flex-shrink\"></a>4.3.flex-shrink</h2><p>flex-shrink定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item</span> {</span><br><span class=\"line\"> <span class=\"attribute\">flex-shrink</span>: <number>; <span class=\"comment\">/* default 1 */</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/pnIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。</p>\n<p>负值对该属性无效</p>\n<hr>\n<h2 id=\"4-4-flex-basis\"><a href=\"#4-4-flex-basis\" class=\"headerlink\" title=\"4.4.flex-basis\"></a>4.4.flex-basis</h2><p>flex-basis定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item</span> {</span><br><span class=\"line\"> <span class=\"attribute\">flex-basis</span>: <length> | auto; <span class=\"comment\">/* default auto */</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间</p>\n<hr>\n<h2 id=\"4-5-flex属性\"><a href=\"#4-5-flex属性\" class=\"headerlink\" title=\"4.5.flex属性\"></a>4.5.flex属性</h2><p>flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item</span> {</span><br><span class=\"line\"> <span class=\"attribute\">flex</span>: none | [ <<span class=\"string\">'flex-grow'</span>> <<span class=\"string\">'flex-shrink'</span>>? || <<span class=\"string\">'flex-basis'</span>> ]</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。</p>\n<p>建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。</p>\n<hr>\n<h2 id=\"4-6-align-self\"><a href=\"#4-6-align-self\" class=\"headerlink\" title=\"4.6.align-self\"></a>4.6.align-self</h2><p>align-self允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item</span> {</span><br><span class=\"line\"> <span class=\"attribute\">align-self</span>: auto | flex-start | flex-end | center | baseline | stretch;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p><img src=\"http://www.ruanyifeng.com/blogimg/asset/2015/bg2015071016.png\"></p>\n<hr>\n<blockquote>\n<p>内容参考自:<a href=\"http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html\">Flex 布局教程:语法篇</a></p>\n</blockquote>\n","categories":["CSS"],"tags":["CSS","CSS布局"]},{"title":"js-斐波拉契数列","url":"/2021/01/15/js-%E6%96%90%E6%B3%A2%E6%8B%89%E5%A5%91%E6%95%B0%E5%88%97/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/JiaKp/embedded/js/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"js-通过递归封装n的阶乘","url":"/2021/01/15/js-%E9%80%9A%E8%BF%87%E9%80%92%E5%BD%92%E5%B0%81%E8%A3%85n%E7%9A%84%E9%98%B6%E4%B9%98/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/diaKp/embedded/js/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n","categories":["JavaScript"],"tags":["JavaScript"]},{"title":"原生js实现图片懒加载","url":"/2021/04/01/%E5%8E%9F%E7%94%9Fjs%E5%AE%9E%E7%8E%B0%E5%9B%BE%E7%89%87%E6%87%92%E5%8A%A0%E8%BD%BD/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-原生JS实现图片懒加载\"><a href=\"#1-原生JS实现图片懒加载\" class=\"headerlink\" title=\"1.原生JS实现图片懒加载\"></a>1.原生JS实现图片懒加载</h1><p>图片懒加载实现原理:对图片进行延迟加载,当图片进入可视化区域再触发加载</p>\n<p>图片懒加载是非常常见的一种性能优化方式,在页面渲染过程中,图片加载往往是影响网页性能的元凶之一。一些图片的大小超过几兆是很常见的事情,如果一个页面有几十张的图片,打开页面会同时请求所有图片资源,需要等待很久图片才能全部加载完成;而且用户很可能并不会浏览完全部图片,造成流量浪费,对用户体验来说非常不友好</p>\n<p>这种情况可以考虑对图片进行懒加载处理,当图片进入可视化区域再请求图片资源,这样可以大大提升网页性能</p>\n<hr>\n<h1 id=\"2-实现思路\"><a href=\"#2-实现思路\" class=\"headerlink\" title=\"2.实现思路\"></a>2.实现思路</h1><p>当图片进入可视化区域后再请求图片资源,那么我们需要知道可视化区域的高度,图片元素距离顶部的高度和当前页面滚动的高度</p>\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/v2-af1ab0c5f34e468e8647135c1f9f51e4_720w.jpg\"></p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"JS\"><figure class=\"iseeu highlight /js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">document</span>.documentElement.clientHeight<span class=\"comment\">//获取屏幕可视区域的高度</span></span><br><span class=\"line\">element.offsetTop<span class=\"comment\">//获取元素相对于文档顶部(offsetParent)的高度</span></span><br><span class=\"line\"><span class=\"built_in\">document</span>.documentElement.scrollTop<span class=\"comment\">//获取浏览器窗口顶部与文档顶部之间的距离,也就是滚动条滚动的距离</span></span><br></pre></td></tr></table></figure></div>\n\n<p>通过上述3个api,我们就可以获取到我们需要的数据,那么便可以推导出:offsetTop-scrollTop < clientHeight,则图片已经进入可视化区域</p>\n<hr>\n<h1 id=\"3-代码实现\"><a href=\"#3-代码实现\" class=\"headerlink\" title=\"3.代码实现\"></a>3.代码实现</h1><iframe width=\"100%\" height=\"340\" src=\"//jsrun.net/CSNKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<blockquote>\n<p>内容参考自:<a href=\"https://zhuanlan.zhihu.com/p/55311726\">原生js实现图片懒加载(lazyLoad)</a></p>\n</blockquote>\n","categories":["JavaScript"],"tags":["JavaScript","性能优化"]},{"title":"一分钟了解text-overflow省略文本","url":"/2021/01/02/%E4%B8%80%E5%88%86%E9%92%9F%E4%BA%86%E8%A7%A3text-overflow%E7%9C%81%E7%95%A5%E6%96%87%E6%9C%AC/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/FtIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>多行省略</p>\n<ol>\n<li>display 为 -webkit-box 或者 -webkit-inline-box;</li>\n<li>-webkit-box-orient 的属性值为 vertical;</li>\n</ol>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/3jIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n","categories":["CSS"],"tags":["CSS"]},{"title":"一张图理解CSS权重","url":"/2021/01/07/%E4%B8%80%E5%BC%A0%E5%9B%BE%E7%90%86%E8%A7%A3CSS%E6%9D%83%E9%87%8D/","content":"<p>一张图理解CSS权重</p>\n<hr>\n<a id=\"more\"></a>\n\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/specifishity.png\"></p>\n<p>0-0-0-0:通配符,子选择器,相邻选择器<br>0-0-0-1:元素选择器,伪元素选择器(:before,:after…)<br>0-0-1-0:类选择器,伪类选择器(:focus,:hover…),属性选择器<br>0-1-0-0:ID选择器<br>1-0-0-0:内联样式(style)<br>1-0-0-0-0:!important</p>\n<hr>\n<blockquote>\n<p>内容参考自:<a href=\"https://specifishity.com/\">https://specifishity.com/</a></p>\n</blockquote>\n","categories":["CSS"],"tags":["CSS"]},{"title":"实现CSS水平垂直居中的8种方法","url":"/2020/12/20/%E5%AE%9E%E7%8E%B0CSS%E6%B0%B4%E5%B9%B3%E5%9E%82%E7%9B%B4%E5%B1%85%E4%B8%AD%E7%9A%848%E7%A7%8D%E6%96%B9%E6%B3%95/","content":"<p>实现CSS水平垂直居中是一道面试的必考题,看似简单,其实是对CSS基础知识的全面检测。</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-常见的CSS居中方式\"><a href=\"#1-常见的CSS居中方式\" class=\"headerlink\" title=\"1.常见的CSS居中方式\"></a>1.常见的CSS居中方式</h1><p>常见的CSS水平垂直居中的方式大概有以下两大类:</p>\n<p>元素居中定宽高:</p>\n<ul>\n<li>absolute + 负margin</li>\n<li>absolute + margin:auto</li>\n<li>absolute + calc</li>\n</ul>\n<p>元素居中不定宽高:</p>\n<ul>\n<li>absolute + transform</li>\n<li>lineheight</li>\n<li>css-table</li>\n<li>flex</li>\n<li>grid</li>\n</ul>\n<hr>\n<h1 id=\"2-元素居中定宽高\"><a href=\"#2-元素居中定宽高\" class=\"headerlink\" title=\"2.元素居中定宽高\"></a>2.元素居中定宽高</h1><h2 id=\"2-1-absolute-负margin\"><a href=\"#2-1-absolute-负margin\" class=\"headerlink\" title=\"2.1.absolute + 负margin\"></a>2.1.absolute + 负margin</h2><p>我们通过绝对定位将子元素基于左上角居中定位,通过负外边距让子元素反方向移动自身的一般距离,实现居中定位:</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/jUIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>这是一种非常常用的方式,缺点是需要提前知道子元素宽高。</p>\n<hr>\n<h2 id=\"2-2-absolute-margin-auto\"><a href=\"#2-2-absolute-margin-auto\" class=\"headerlink\" title=\"2.2.absolute + margin:auto\"></a>2.2.absolute + margin:auto</h2><p>这种方式通过设置各方向距离为0,再设置margin:auto,实现各方向上的居中:</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/RUIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>本方法缺点也是需要提前知道子元素宽高。</p>\n<hr>\n<h2 id=\"2-3-absolute-calc\"><a href=\"#2-3-absolute-calc\" class=\"headerlink\" title=\"2.3.absolute + calc\"></a>2.3.absolute + calc</h2><p>这种方式其实是第一种的优化,CSS3为我们添加了calc计算属性,因此我们能够直接用(50%-宽高的一半)轻松实现布局:</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/K9IKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>本方法需要兼容CSS3,需要提前知道子元素宽高。</p>\n<hr>\n<h1 id=\"3-元素居中不定宽高\"><a href=\"#3-元素居中不定宽高\" class=\"headerlink\" title=\"3.元素居中不定宽高\"></a>3.元素居中不定宽高</h1><h2 id=\"3-1-absolute-transform\"><a href=\"#3-1-absolute-transform\" class=\"headerlink\" title=\"3.1.absolute + transform\"></a>3.1.absolute + transform</h2><p>这种方式仍然基于绝对定位,不同的是该方法使用CSS新增的transform,其属性translate也可以设定百分比,是相对于自身大小的宽和高,不再需要提前知道子元素宽高:</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/q9IKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h2 id=\"3-2-lineheight\"><a href=\"#3-2-lineheight\" class=\"headerlink\" title=\"3.2.lineheight\"></a>3.2.lineheight</h2><p>利用行内元素居中属性也可以做到水平垂直对齐:</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/f9IKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h2 id=\"3-3-css-table\"><a href=\"#3-3-css-table\" class=\"headerlink\" title=\"3.3.css-table\"></a>3.3.css-table</h2><p>CSS的display:table-cell可以帮我们将普通元素转化为table元素,通过这个特性也可以实现水平垂直居中:</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/29IKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h2 id=\"3-4-flex\"><a href=\"#3-4-flex\" class=\"headerlink\" title=\"3.4.flex\"></a>3.4.flex</h2><p>flex布局作为现代布局方式,可以通过几行代码优雅的实现水平垂直居中:</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/v9IKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>缺点:需要考虑兼容性。</p>\n<hr>\n<h2 id=\"3-5-grid\"><a href=\"#3-5-grid\" class=\"headerlink\" title=\"3.5.grid\"></a>3.5.grid</h2><p>与flex布局相似,但兼容性不如flex:</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/w9IKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h1 id=\"4-总结\"><a href=\"#4-总结\" class=\"headerlink\" title=\"4.总结\"></a>4.总结</h1><ul>\n<li>PC端有兼容性要求,宽高固定,推荐absolute + 负margin</li>\n<li>PC端有兼容性要求,宽高不固定,推荐css-table</li>\n<li>PC端无兼容性要求,推荐flex</li>\n<li>移动端推荐flex</li>\n</ul>\n<hr>\n","categories":["CSS"],"tags":["CSS","CSS布局"]},{"title":"实现一个简易的微信朋友圈Demo","url":"/2021/01/08/%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E7%AE%80%E6%98%93%E7%9A%84%E5%BE%AE%E4%BF%A1%E6%9C%8B%E5%8F%8B%E5%9C%88Demo/","content":"<p>实现一个简易的微信朋友圈Demo</p>\n<hr>\n<a id=\"more\"></a>\n\n<iframe width=\"100%\" height=\"2000\" src=\"//jsrun.net/cBIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<blockquote>\n<p>内容参考自:<a href=\"https://mp.weixin.qq.com/s/BUMaJXJ2bD0FcZ5kMI_WrA\">用前端仿写朋友圈</a></p>\n</blockquote>\n","categories":["Demo"],"tags":["Demo"]},{"title":"所有编程语言都离不开的三大数据类型","url":"/2021/02/01/%E6%89%80%E6%9C%89%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80%E9%83%BD%E7%A6%BB%E4%B8%8D%E5%BC%80%E7%9A%84%E4%B8%89%E5%A4%A7%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/","content":"<p>阅读全文,了解更多</p>\n<hr>\n<a id=\"more\"></a>\n\n<p>所有编程语言都离不开的三大数据类型:</p>\n<ul>\n<li>标量(scalar) -> 字符串和数字</li>\n<li>序列(sequence) -> 数组(array)和列表(list)</li>\n<li>映射(mapping) -> 键值对 键名: 键值</li>\n</ul>\n<hr>\n","categories":["日积月累"],"tags":["日积月累"]},{"title":"滑动菜单demo","url":"/2021/01/07/%E6%BB%91%E5%8A%A8%E8%8F%9C%E5%8D%95demo/","content":"<p>一个简单的滑动菜单demo</p>\n<hr>\n<a id=\"more\"></a>\n\n<iframe width=\"100%\" height=\"500\" src=\"//jsrun.net/MAIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<blockquote>\n<p>内容参考自:<a href=\"https://mp.weixin.qq.com/s/hCbRtgZ9v0T9OJhJ15JAeA\">第 6 天:设计一个左右滑动的菜单</a></p>\n</blockquote>\n","categories":["Demo"],"tags":["Demo"]},{"title":"Grid布局基础","url":"/2020/12/05/Grid%E5%B8%83%E5%B1%80%E5%9F%BA%E7%A1%80/","content":"<p>Grid布局是一种强大的CSS布局方案,操作非常灵活,它将网页划分为一个个网格区域,通过合并这些小网格,可以快速组合成各种各样的布局样式,以前需要通过大量CSS代码来完成的复杂样式,现在可以直接通过操作和合并各网格区域实现想要的样式,从而达到高效开发。</p>\n<hr>\n<a id=\"more\"></a>\n\n<h1 id=\"1-Grid布局与Flex布局的关系?\"><a href=\"#1-Grid布局与Flex布局的关系?\" class=\"headerlink\" title=\"1.Grid布局与Flex布局的关系?\"></a>1.Grid布局与Flex布局的关系?</h1><p>Grid布局和Flex布局具有一定的相似性,可以近似看作是Flex布局的升级版。Flex布局是基于轴线来进行布局,可以看作是一维布局,难以快速处理一些复杂布局;Grid引入了行和列的概念,通过网格线将页面划分为许多块单元格,像拼图一样自由操作各单元格,可以看作二维布局。</p>\n<hr>\n<h1 id=\"2-基本概念\"><a href=\"#2-基本概念\" class=\"headerlink\" title=\"2.基本概念\"></a>2.基本概念</h1><h2 id=\"2-1-容器与项目\"><a href=\"#2-1-容器与项目\" class=\"headerlink\" title=\"2.1.容器与项目\"></a>2.1.容器与项目</h2><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"HTML\"><figure class=\"iseeu highlight /html\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"tag\"><<span class=\"name\">div</span>></span></span><br><span class=\"line\"> <span class=\"tag\"><<span class=\"name\">div</span>></span><span class=\"tag\"><<span class=\"name\">p</span>></span>1<span class=\"tag\"></<span class=\"name\">p</span>></span><span class=\"tag\"></<span class=\"name\">div</span>></span></span><br><span class=\"line\"> <span class=\"tag\"><<span class=\"name\">div</span>></span><span class=\"tag\"><<span class=\"name\">p</span>></span>2<span class=\"tag\"></<span class=\"name\">p</span>></span><span class=\"tag\"></<span class=\"name\">div</span>></span></span><br><span class=\"line\"> <span class=\"tag\"><<span class=\"name\">div</span>></span><span class=\"tag\"><<span class=\"name\">p</span>></span>3<span class=\"tag\"></<span class=\"name\">p</span>></span><span class=\"tag\"></<span class=\"name\">div</span>></span></span><br><span class=\"line\"><span class=\"tag\"></<span class=\"name\">div</span>></span></span><br></pre></td></tr></table></figure></div>\n\n<p>采用Grid布局的区域被称为容器(container),容器内部的顶层子元素就是项目(item),Grid布局只对项目有效,不对项目的子元素有效,如上方代码块中<p>元素就不是项目。</p>\n<hr>\n<h2 id=\"2-2-行和列\"><a href=\"#2-2-行和列\" class=\"headerlink\" title=\"2.2.行和列\"></a>2.2.行和列</h2><p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/%E5%9C%A3%E6%9D%AF%E5%B8%83%E5%B1%80-grid.PNG\" alt=\"圣杯布局-Grid\"></p>\n<p>如图,上述区域被5条网格线水平分为3行垂直分为4列</p>\n<hr>\n<h2 id=\"2-3-单元格\"><a href=\"#2-3-单元格\" class=\"headerlink\" title=\"2.3.单元格\"></a>2.3.单元格</h2><p>行和列的交叉区域,称为”单元格”(cell)。</p>\n<p>正常情况下,n行和m列会产生n x m个单元格。如上图,3行4列会产生12个单元格。</p>\n<hr>\n<h2 id=\"2-4-网格线\"><a href=\"#2-4-网格线\" class=\"headerlink\" title=\"2.4.网格线\"></a>2.4.网格线</h2><p>划分网格的线,称为”网格线”(grid line)。水平网格线划分出行,垂直网格线划分出列。</p>\n<p>正常情况下,n行有n + 1根水平网格线,m列有m + 1根垂直网格线,如上图,3行有4根水平网格线,4列有4根垂直网格线。</p>\n<hr>\n<h1 id=\"3-容器属性\"><a href=\"#3-容器属性\" class=\"headerlink\" title=\"3.容器属性\"></a>3.容器属性</h1><p>Grid 布局的属性分成两类。一类定义在容器上面,称为容器属性;另一类定义在项目上面,称为项目属性。首先介绍容器属性。</p>\n<h2 id=\"3-1-display属性\"><a href=\"#3-1-display属性\" class=\"headerlink\" title=\"3.1. display属性\"></a>3.1. display属性</h2><p>指定一个容器采用Grid布局</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-tag\">div</span> {</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\">} </span><br></pre></td></tr></table></figure></div>\n\n<p>效果如图:</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/gKIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>默认情况下,容器是块元素,如果需要,也可以设置为行内块元素:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-tag\">div</span> {</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: inline-block;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>效果如图:</p>\n<iframe width=\"100%\" height=\"220\" src=\"//jsrun.net/yKIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<blockquote>\n<p>注意:设为网格布局以后,容器子元素(项目)的float、display: inline-block、display: table-cell、vertical-align和column-*等设置都将失效。</p>\n</blockquote>\n<hr>\n<h2 id=\"3-2-grid-template-columns和grid-template-rows属性\"><a href=\"#3-2-grid-template-columns和grid-template-rows属性\" class=\"headerlink\" title=\"3.2. grid-template-columns和grid-template-rows属性\"></a>3.2. grid-template-columns和grid-template-rows属性</h2><p>容器指定了网格布局以后,接着就要划分行和列。grid-template-columns属性定义每一列的列宽,grid-template-rows属性定义每一行的行高。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"number\">100px</span> <span class=\"number\">100px</span> <span class=\"number\">100px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-rows</span>: <span class=\"number\">100px</span> <span class=\"number\">100px</span> <span class=\"number\">100px</span>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"366\" src=\"//jsrun.net/vKIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>除了绝对单位,也可以使用百分比布局,单元格的大小取决于父容器的大小:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"number\">33.3%</span> <span class=\"number\">33.3%</span> <span class=\"number\">33.3%</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-rows</span>: <span class=\"number\">33.3%</span> <span class=\"number\">33.3%</span> <span class=\"number\">33.3%</span>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"200\" src=\"//jsrun.net/6KIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<h3 id=\"3-2-1-repeat(手动填充)\"><a href=\"#3-2-1-repeat(手动填充)\" class=\"headerlink\" title=\"3.2.1.repeat(手动填充)\"></a>3.2.1.repeat(手动填充)</h3><p>有时候,重复写同样的值非常麻烦,尤其网格很多时。这时,可以使用repeat()函数,简化重复的值。上面的代码用repeat()改写如下:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"built_in\">repeat</span>(<span class=\"number\">3</span>, <span class=\"number\">33.33%</span>);</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-rows</span>: <span class=\"built_in\">repeat</span>(<span class=\"number\">3</span>, <span class=\"number\">33.33%</span>);</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>repeat()接受两个参数,第一个参数是重复的次数(上图示例是3),第二个参数是所要重复的值:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span>{</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"built_in\">repeat</span>(<span class=\"number\">2</span>,<span class=\"number\">100px</span> <span class=\"number\">60px</span> <span class=\"number\">40px</span>);</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-rows</span>: <span class=\"built_in\">repeat</span>(<span class=\"number\">3</span>, <span class=\"number\">50px</span>);</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"180\" src=\"//jsrun.net/NKIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>我们发现,一共有9个项目,但显然网格线划分出的单元格要多于我们的项目,那么多余的单元格还存在呢?让我们进入浏览器一探究竟:</p>\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/grid.PNG\" alt=\"grid\"></p>\n<p>显然多余的单元格仍然存在,空白部分也按照我们设置的网格线正确划分出了单元格区域。</p>\n<hr>\n<h3 id=\"3-2-2-auto-fill(自动填充)\"><a href=\"#3-2-2-auto-fill(自动填充)\" class=\"headerlink\" title=\"3.2.2.auto-fill(自动填充)\"></a>3.2.2.auto-fill(自动填充)</h3><p>单元格的大小是固定的,但是容器的大小不确定。如果希望每一行(或每一列)自动填充尽可能多的单元格,可以使用auto-fill关键字自动填充。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span>{</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"built_in\">repeat</span>(auto-fill, <span class=\"number\">100px</span>);</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"200\" src=\"//jsrun.net/9KIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h3 id=\"3-2-3-fr(等比例填充)\"><a href=\"#3-2-3-fr(等比例填充)\" class=\"headerlink\" title=\"3.2.3.fr(等比例填充)\"></a>3.2.3.fr(等比例填充)</h3><p>为了方便表示比例关系,网格布局提供了fr关键字(fraction 的缩写,意为”片段”)。如果两列的宽度分别为1fr和2fr,就表示后者是前者的两倍。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span>{</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"number\">1</span>fr <span class=\"number\">2</span>fr;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>宽度被划分成3份,第一列占1/3,第二列占2/3。</p>\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/eKIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>也可以和绝对长度一起使用:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span>{</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"number\">400px</span> <span class=\"number\">1</span>fr <span class=\"number\">2</span>fr;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>第一列固定宽度400px,剩余空间分成3等份,第二列占其中的1/3,第三列占其余2/3。</p>\n<iframe width=\"100%\" height=\"200\" src=\"//jsrun.net/QKIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h3 id=\"3-2-4-auto(浏览器填充)\"><a href=\"#3-2-4-auto(浏览器填充)\" class=\"headerlink\" title=\"3.2.4.auto(浏览器填充)\"></a>3.2.4.auto(浏览器填充)</h3><p>通过auto关键字让浏览器自己决定合适的长度,用简短的代码快速完成圣杯布局。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span>{</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"number\">100px</span> auto <span class=\"number\">100px</span>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"220\" src=\"//jsrun.net/zKIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h3 id=\"3-2-5-网格线名称\"><a href=\"#3-2-5-网格线名称\" class=\"headerlink\" title=\"3.2.5.网格线名称\"></a>3.2.5.网格线名称</h3><p>可以使用方括号[],指定每一根网格线的名字,方便以后的引用。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span>{</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: [c1] <span class=\"number\">100px</span> [c2] auto [c3] <span class=\"number\">100px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-rows</span>: [r1] <span class=\"number\">100px</span> [r2] <span class=\"number\">100px</span> [r3] <span class=\"number\">100px</span>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/grid-line-names.PNG\" alt=\"grid-line-names\"></p>\n<hr>\n<h3 id=\"3-2-6-快速搭建\"><a href=\"#3-2-6-快速搭建\" class=\"headerlink\" title=\"3.2.6.快速搭建\"></a>3.2.6.快速搭建</h3><h4 id=\"快速开发三栏布局\"><a href=\"#快速开发三栏布局\" class=\"headerlink\" title=\"快速开发三栏布局\"></a>快速开发三栏布局</h4><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"number\">20%</span> <span class=\"number\">50%</span> <span class=\"number\">30%</span>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"160\" src=\"//jsrun.net/xKIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h4 id=\"快速开发12列栅格布局\"><a href=\"#快速开发12列栅格布局\" class=\"headerlink\" title=\"快速开发12列栅格布局\"></a>快速开发12列栅格布局</h4><div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span>{</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"built_in\">repeat</span>(<span class=\"number\">12</span>, <span class=\"number\">1</span>fr);</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-rows</span>: <span class=\"number\">80px</span>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"150\" src=\"//jsrun.net/HKIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h2 id=\"3-3-row-gap属性,column-gap属性,gap属性\"><a href=\"#3-3-row-gap属性,column-gap属性,gap属性\" class=\"headerlink\" title=\"3.3.row-gap属性,column-gap属性,gap属性\"></a>3.3.row-gap属性,column-gap属性,gap属性</h2><p>row-gap属性设置行与行的间隔(行间距),column-gap属性设置列与列的间隔(列间距)。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span>{</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"built_in\">repeat</span>(<span class=\"number\">3</span>, <span class=\"number\">150px</span>);</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-rows</span>: <span class=\"built_in\">repeat</span>(<span class=\"number\">3</span>, <span class=\"number\">50px</span>);</span><br><span class=\"line\"> <span class=\"attribute\">row-gap</span>: <span class=\"number\">20px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">column-gap</span>: <span class=\"number\">20px</span>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"300\" src=\"//jsrun.net/5KIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>gap属性是column-gap和row-gap的合并简写</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span>{</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"built_in\">repeat</span>(<span class=\"number\">3</span>, <span class=\"number\">150px</span>);</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-rows</span>: <span class=\"built_in\">repeat</span>(<span class=\"number\">3</span>, <span class=\"number\">50px</span>);</span><br><span class=\"line\"> <span class=\"attribute\">gap</span>: <span class=\"number\">20px</span> <span class=\"number\">20px</span>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>如果gap省略了第二个值,浏览器认为第二个值等于第一个值。</p>\n<hr>\n<h2 id=\"3-4-grid-template-areas-属性\"><a href=\"#3-4-grid-template-areas-属性\" class=\"headerlink\" title=\"3.4.grid-template-areas 属性\"></a>3.4.grid-template-areas 属性</h2><p>网格布局允许指定区域(area),一个区域由单个或多个单元格组成。grid-template-areas属性用于定义区域。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span>{</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"number\">100px</span> <span class=\"number\">100px</span> <span class=\"number\">100px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-rows</span>: <span class=\"number\">100px</span> <span class=\"number\">100px</span> <span class=\"number\">100px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-areas</span>: <span class=\"string\">'a b c'</span></span><br><span class=\"line\"> <span class=\"string\">'d e f'</span></span><br><span class=\"line\"> <span class=\"string\">'g h i'</span>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"370\" src=\"//jsrun.net/tKIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>上面代码先划分出9个单元格,然后将其定名为a到i的九个区域,分别对应这九个单元格:</p>\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/grid-template-areas.PNG\" alt=\"grid-template-areas-1\"></p>\n<p>多个单元格合并成一个区域的写法如下:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span>{</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"number\">100px</span> <span class=\"number\">100px</span> <span class=\"number\">100px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-rows</span>: <span class=\"number\">100px</span> <span class=\"number\">100px</span> <span class=\"number\">100px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-areas</span>: <span class=\"string\">'a a a'</span></span><br><span class=\"line\"> <span class=\"string\">'b b b'</span></span><br><span class=\"line\"> <span class=\"string\">'c c c'</span>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/grid-templete-areas-abc.PNG\" alt=\"grid-template-areas-2\"></p>\n<p>如果某区域不需要定义,可以用’.’省略:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span>{</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-areas</span>: <span class=\"string\">'a . c'</span></span><br><span class=\"line\"> <span class=\"string\">'d . f'</span></span><br><span class=\"line\"> <span class=\"string\">'g . i'</span>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/grid-templete-areas-pass.PNG\" alt=\"grid-template-areas-3\"></p>\n<blockquote>\n<p>注意,区域的命名会影响到网格线。每个区域的起始网格线,会自动命名为区域名-start,终止网格线自动命名为区域名-end。</p>\n</blockquote>\n<hr>\n<h2 id=\"3-5-grid-auto-flow-属性\"><a href=\"#3-5-grid-auto-flow-属性\" class=\"headerlink\" title=\"3.5.grid-auto-flow 属性\"></a>3.5.grid-auto-flow 属性</h2><p>划分单元格后,容器内项目会按照顺序自动排列,默认的放置顺序是先行后列。排序顺序由grid-auto-flow决定,默认值是row,我们将其设置为column,变成先列后行:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span>{</span><br><span class=\"line\"> <span class=\"attribute\">grid-auto-flow</span>: column;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"366\" src=\"//jsrun.net/ypIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<blockquote>\n<p>注意:grid-auto-flow属性除了设置成row和column,还可以设成row dense和column dense。这两个值主要用于某些项目指定位置以后,剩下的项目怎么自动放置。</p>\n</blockquote>\n<p>在一些特殊情况下,如下图,前两个项目占2个单元格,在默认grid-auto-flow: row条件下,一行排不下前两个项目,第一行最后会产生空白单元格:</p>\n<iframe width=\"100%\" height=\"460\" src=\"//jsrun.net/WpIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>可以通过grid-auto-flow: row dense 或 grid-auto-flow: column dense 解决,优先填满内容,然后再顺序排列:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span>{</span><br><span class=\"line\"> <span class=\"attribute\">grid-auto-flow</span>: row dense;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"460\" src=\"//jsrun.net/fpIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h2 id=\"3-6-justify-items-属性,align-items-属性,place-items-属性\"><a href=\"#3-6-justify-items-属性,align-items-属性,place-items-属性\" class=\"headerlink\" title=\"3.6.justify-items 属性,align-items 属性,place-items 属性\"></a>3.6.justify-items 属性,align-items 属性,place-items 属性</h2><p>justify-items属性设置单元格内项目的水平位置(左中右),align-items属性设置单元格内项目的垂直位置(上中下)。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">justify-items</span>: start | end | center | stretch;</span><br><span class=\"line\"> <span class=\"attribute\">align-items</span>: start | end | center | stretch;</span><br><span class=\"line\"> <span class=\"comment\">/* start:对齐单元格的起始边缘 */</span></span><br><span class=\"line\"> <span class=\"comment\">/* end:对齐单元格的结束边缘 */</span></span><br><span class=\"line\"> <span class=\"comment\">/* center:单元格内部居中 */</span></span><br><span class=\"line\"> <span class=\"comment\">/* stretch:拉伸,占满单元格的整个宽度(默认值)*/</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>justify-items:</p>\n<iframe width=\"100%\" height=\"366\" src=\"//jsrun.net/LpIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/jusify-items.PNG\" alt=\"justify-items\"></p>\n<p>align-items:</p>\n<iframe width=\"100%\" height=\"366\" src=\"//jsrun.net/6pIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/align-items.PNG\" alt=\"align-items\"></p>\n<blockquote>\n<p>注意:place-items属性是align-items属性和justify-items属性的合并简写形式</p>\n</blockquote>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span> {</span><br><span class=\"line\"> <span class=\"comment\">/* place-items: <align-items> <justify-items>; */</span></span><br><span class=\"line\"> <span class=\"attribute\">place-items</span>: start end;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"3-7-justify-content-属性,align-content-属性,place-content-属性\"><a href=\"#3-7-justify-content-属性,align-content-属性,place-content-属性\" class=\"headerlink\" title=\"3.7.justify-content 属性,align-content 属性,place-content 属性\"></a>3.7.justify-content 属性,align-content 属性,place-content 属性</h2><p>justify-content属性是整个内容区域在容器里面的水平位置(左中右),align-content属性是整个内容区域的垂直位置(上中下)</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">justify-content</span>: start | end | center | space-around | space-between | space-evenly;</span><br><span class=\"line\"> <span class=\"attribute\">align-content</span>: start | end | center | space-around | space-between | space-evenly; </span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>justify-content: end</p>\n<iframe width=\"100%\" height=\"366\" src=\"//jsrun.net/NpIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-tag\">space-around</span> <span class=\"selector-tag\">-</span> 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍</span><br><span class=\"line\"><span class=\"selector-tag\">space-between</span> <span class=\"selector-tag\">-</span> 项目与项目的间隔相等,项目与容器边框之间没有间隔</span><br><span class=\"line\"><span class=\"selector-tag\">space-evenly</span> <span class=\"selector-tag\">-</span> 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔</span><br></pre></td></tr></table></figure></div>\n\n<p><img src=\"https://gitee.com/caldey/BlogImage/raw/master/img/justify-content.PNG\" alt=\"justify-content\"></p>\n<blockquote>\n<p>注意:place-content属性是align-content属性和justify-content属性的合并简写形式</p>\n</blockquote>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span> {</span><br><span class=\"line\"> <span class=\"comment\">/* place-content: <align-content> <justify-content>; */</span></span><br><span class=\"line\"> <span class=\"attribute\">place-content</span>: space-around space-evenly;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"3-8-grid-auto-columns-属性,grid-auto-rows-属性\"><a href=\"#3-8-grid-auto-columns-属性,grid-auto-rows-属性\" class=\"headerlink\" title=\"3.8.grid-auto-columns 属性,grid-auto-rows 属性\"></a>3.8.grid-auto-columns 属性,grid-auto-rows 属性</h2><p>如果一个划分好的网格只有3行3列,但是某一个项目指定在第5行。这时,浏览器会自动生成多余的网格,以便放置项目。</p>\n<p>grid-auto-columns属性和grid-auto-rows属性用来设置,浏览器自动创建的多余网格的列宽和行高。它们的写法与grid-template-columns和grid-template-rows完全相同。如果不指定这两个属性,浏览器完全根据单元格内容的大小,决定新增网格的列宽和行高。</p>\n<p>下图为一个3X3的网格,8号项目指定在4行2列,9号项目指定在5行3列,网格外新增的单元格高度统一指定为50px:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span>{</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"number\">100px</span> <span class=\"number\">100px</span> <span class=\"number\">100px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-rows</span>: <span class=\"number\">100px</span> <span class=\"number\">100px</span> <span class=\"number\">100px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-auto-rows</span>: <span class=\"number\">50px</span>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"500\" src=\"//jsrun.net/zpIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<hr>\n<h1 id=\"4-项目属性\"><a href=\"#4-项目属性\" class=\"headerlink\" title=\"4.项目属性\"></a>4.项目属性</h1><h2 id=\"4-1-grid-column-start-属性,grid-column-end-属性,grid-row-start-属性,grid-row-end-属性\"><a href=\"#4-1-grid-column-start-属性,grid-column-end-属性,grid-row-start-属性,grid-row-end-属性\" class=\"headerlink\" title=\"4.1.grid-column-start 属性,grid-column-end 属性,grid-row-start 属性,grid-row-end 属性\"></a>4.1.grid-column-start 属性,grid-column-end 属性,grid-row-start 属性,grid-row-end 属性</h2><p>容器内项目的位置是可以指定的,具体就是指定项目的四个边框对应哪个网格线。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-tag\">grid-column-start</span>:左边框所在的垂直网格线</span><br><span class=\"line\"><span class=\"selector-tag\">grid-column-end</span>:右边框所在的垂直网格线</span><br><span class=\"line\"><span class=\"selector-tag\">grid-row-start</span>:上边框所在的水平网格线</span><br><span class=\"line\"><span class=\"selector-tag\">grid-row-end</span>:下边框所在的水平网格线</span><br></pre></td></tr></table></figure></div>\n\n<p>我们指定1号项目从第二条垂直网格线开始,到第四条垂直网格线结束:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item-1</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-column-start</span>: <span class=\"number\">2</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-column-end</span>: <span class=\"number\">4</span>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"460\" src=\"//jsrun.net/PpIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>除了1号项目外,其他项目我们都没有指定位置,由浏览器自动布局,它们的位置由grid-auto-flow属性决定,可以通过更改默认属性值row为column,row dense,column dense来观察布局位置发生了什么变化。</p>\n<p>同时指定1号项目的4个边框位置:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item-1</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-column-start</span>: <span class=\"number\">2</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-column-end</span>: <span class=\"number\">4</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-row-start</span>: <span class=\"number\">2</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-row-end</span>: <span class=\"number\">4</span>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"460\" src=\"//jsrun.net/xpIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>在<a href=\"#3-4-grid-template-areas-%E5%B1%9E%E6%80%A7\">上文</a>中,我们注意到命名区域的起始和终止网格线会被自动命名为区域名+start,区域名+end,我们可以通过将项目的边框命名成网格线名字,从而快速将项目移动到指定命名区域:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span>{</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-areas</span>: <span class=\"string\">'header header header'</span></span><br><span class=\"line\"> <span class=\"string\">'content content sidebar'</span></span><br><span class=\"line\"> <span class=\"string\">'footer footer footer'</span>;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.item-1</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-column-start</span>: header-start;</span><br><span class=\"line\"> <span class=\"attribute\">grid-column-end</span>: header-end; </span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.item-2</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-column-start</span>: content-start;</span><br><span class=\"line\"> <span class=\"attribute\">grid-column-end</span>: content-end; </span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.item-3</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-column-start</span>: sidebar-start;</span><br><span class=\"line\"> <span class=\"attribute\">grid-column-end</span>: sidebar-end; </span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.item-4</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-column-start</span>: footer-start;</span><br><span class=\"line\"> <span class=\"attribute\">grid-column-end</span>: footer-end; </span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"366\" src=\"//jsrun.net/GpIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>这四个属性的值还可以使用span关键字,表示”跨越”,即左右边框(上下边框)之间跨越多少个网格。</p>\n<p>1号项目的左边框到右边框跨越2个网格:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item-1</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-column-start</span>: span <span class=\"number\">2</span>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"460\" src=\"//jsrun.net/DpIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>如果使用这四个属性产生了项目的重叠,可以通过调整z-index属性指定项目的重叠顺序。</p>\n<hr>\n<h2 id=\"4-2-grid-column-属性,grid-row-属性\"><a href=\"#4-2-grid-column-属性,grid-row-属性\" class=\"headerlink\" title=\"4.2.grid-column 属性,grid-row 属性\"></a>4.2.grid-column 属性,grid-row 属性</h2><p>grid-column,grid-row两个属性是上文四个属性的合并简写,合并了start和end。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-column</span>: <start-line> / <end-line>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-row</span>: <start-line> / <end-line>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<hr>\n<h2 id=\"4-3-grid-area-属性\"><a href=\"#4-3-grid-area-属性\" class=\"headerlink\" title=\"4.3.grid-area 属性\"></a>4.3.grid-area 属性</h2><p>grid-area属性指定项目放在哪一个区域。</p>\n<p>我们指定一个3X3网格命名区域为a-i九个区域,将1号项目指定为e区域:</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-id\">#container</span>{</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-areas</span>: <span class=\"string\">'a b c'</span></span><br><span class=\"line\"> <span class=\"string\">'d e f'</span></span><br><span class=\"line\"> <span class=\"string\">'g h i'</span>;</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"selector-class\">.item-1</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-area</span>: e;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<iframe width=\"100%\" height=\"366\" src=\"//jsrun.net/npIKp/embedded/all/light\" allowfullscreen=\"allowfullscreen\" frameborder=\"0\"></iframe>\n\n<p>grid-area属性还可用作grid-row-start、grid-column-start、grid-row-end、grid-column-end的合并简写形式,直接指定项目的位置。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-area</span>: <row-start> / <column-start> / <row-end> / <column-end>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<h2 id=\"4-4-justify-self-属性,align-self-属性,place-self-属性\"><a href=\"#4-4-justify-self-属性,align-self-属性,place-self-属性\" class=\"headerlink\" title=\"4.4.justify-self 属性,align-self 属性,place-self 属性\"></a>4.4.justify-self 属性,align-self 属性,place-self 属性</h2><p>justify-self属性设置单元格内容的水平位置(左中右),跟justify-items属性的用法完全一致,但只作用于单个项目。</p>\n<p>align-self属性设置单元格内容的垂直位置(上中下),跟align-items属性的用法完全一致,也是只作用于单个项目。</p>\n<div class=\"highlight-wrap\"autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" contenteditable=\"true\"data-rel=\"CSS\"><figure class=\"iseeu highlight /css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item</span> {</span><br><span class=\"line\"> <span class=\"attribute\">justify-self</span>: start | end | center | stretch;</span><br><span class=\"line\"> <span class=\"attribute\">align-self</span>: start | end | center | stretch;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure></div>\n\n<p>这2个属性的用法与<a href=\"#3-6-justify-items-%E5%B1%9E%E6%80%A7%EF%BC%8Calign-items-%E5%B1%9E%E6%80%A7%EF%BC%8Cplace-items-%E5%B1%9E%E6%80%A7\">上文</a>完全一致,在此不再过多赘述,区别在于此属性只作用于单独项目。</p>\n<hr>\n<blockquote>\n<p>内容参考自:<a href=\"http://www.ruanyifeng.com/blog/2019/03/grid-layout-tutorial.html\">CSS Grid 网格布局教程</a></p>\n</blockquote>\n","categories":["CSS"],"tags":["CSS","CSS布局"]}]