ES6常用知识学习札记
<p><code></p>
<p><strong>转载请注明出处</strong></p>
<p><strong>原文连接</strong> <a href="http://blog.huanghanlian.com/article/5c7aa6c7bf3acc0864870f9d" rel="nofollow noreferrer" target="_blank">http://blog.huanghanlian.com/article/5c7aa6c7bf3acc0864870f9d</a></p>
<h2 id="articleHeader0"><a href="http://www.js-code.com/tag/es6" title="es6" target="_blank">es6</a> 是什么</h2>
<p>首先弄明白ECMA和js的关系。ECMA是标准,Javascript是ECMA的实现。因为js也是一种语言,但凡语言都有一套标准,而ECMA就是<a href="http://www.js-code.com/tag/java" title="java" target="_blank">java</a>script的标准。 在2015年正式发布了ECMAscript6.0,简称ES6,又称为ECMAscript2015。</p>
<ol>
<li>
<p>历史</p>
<ol>
<li>
<p><a href="http://www.js-code.com/tag/ecmascript" title="ECMAScript" target="_blank">ECMAScript</a>和Javascript</p>
<ul>
<li>
<p>ECMA是标准,JS是实现</p>
<ul>
<li>类似于<a href="http://www.js-code.com/tag/html" title="HTML" target="_blank">HTML</a>5是标准,IE10,Chrome,FF都是实现</li>
<li>换句话说,将来也能有其他XXXScript来实现ECMA</li>
</ul>
</li>
<li><a href="http://www.js-code.com/tag/ecmascript" title="ECMAScript" target="_blank">ECMAScript</a>简称<strong>ECMA或ES</strong>
</li>
<li>
<p>目前版本</p>
<ul>
<li>低级浏览器主要支持ES 3.1</li>
<li>高级浏览器正在从ES 5过度ES 6</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li>历史版本</li>
</ol>
<table>
<thead>
<tr>
<th>时间</th>
<th>ECMA</th>
<th>JS</th>
<th>解释</th>
</tr>
</thead>
<tbody>
<tr>
<td>1996.11</td>
<td>EC 1.0</td>
<td>JS稳定</td>
<td>Netscript将js提交给ECMA组织,ES正式出现</td>
</tr>
<tr>
<td>1998.06</td>
<td>ES 2.0</td>
<td> </td>
<td>ES2正式发布</td>
</tr>
<tr>
<td>1999.12</td>
<td>ES 3.0</td>
<td> </td>
<td>ES3被广泛接受</td>
</tr>
<tr>
<td>2007.10</td>
<td>ES 4.0</td>
<td> </td>
<td>ES4过于激进,被废了</td>
</tr>
<tr>
<td>2008.07</td>
<td>ES 3.1</td>
<td> </td>
<td>4.0退化为严重缩水版的3.1<br/>因为吵得太厉害,所以ES3.1代号为Harmony(和谐)</td>
</tr>
<tr>
<td>2009.12</td>
<td>ES 5.0</td>
<td> </td>
<td>ES5正式发布<br/>同时公布了JavaScript.next也就是后来的ES6.0</td>
</tr>
<tr>
<td>2011.06</td>
<td>ES 5.1</td>
<td> </td>
<td>ES5.1成为了ISO国际标准</td>
</tr>
<tr>
<td>2013.03</td>
<td>ES 6.0</td>
<td> </td>
<td>ES6.0草案定稿</td>
</tr>
<tr>
<td>2013.12</td>
<td>ES 6.0</td>
<td> </td>
<td>ES6.0草案发布</td>
</tr>
<tr>
<td>2015.06</td>
<td>ES 6.0</td>
<td> </td>
<td>ES6.0预计发布正式版<br/>JavaScript.next开始指向ES 7.0</td>
</tr>
</tbody>
</table>
<h2 id="articleHeader1">ES6兼容性和新特性</h2>
<p><strong><a href="http://www.js-code.com/tag/es5" title="es5" target="_blank">es5</a>兼容性</strong></p>
<p><a href="http://kangax.github.io/compat-table/es5/" rel="nofollow noreferrer" target="_blank">http://kangax.github.io/compat-table/es5/</a></p>
<p><span class="img-wrap"><img data-src="http://blog.huanghanlian.com/uploads/article/3f4598b9-5df6-43e3-a5c1-8d9f2a10ea55.png" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="继小鹏" title="继小鹏" style="cursor: pointer;"></span></p>
<p><strong><a href="http://www.js-code.com/tag/es6" title="es6" target="_blank">es6</a>兼容性</strong></p>
<p><a href="http://kangax.github.io/compat-table/es6/" rel="nofollow noreferrer" target="_blank">http://kangax.github.io/compat-table/es6/</a></p>
<p><span class="img-wrap"><img data-src="http://blog.huanghanlian.com/uploads/article/f1dc9d28-667d-401b-818b-070e9825bb62.png" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="继小鹏" title="继小鹏" style="cursor: pointer;"></span></p>
<p>ES6(ES2015)-- IE10+,Chrome,FireFox,移动端,NodeJS。这些环境基本上都是认得,都能兼容</p>
<p>但是有需求兼容ie怎么办</p>
<p>有两种办法</p>
<blockquote><p>比方说在移动端或者是混合开发当中,多去用用ES6,在老的版本中不用。惹不起咋躲得起。</p>
<p>编译,转换</p>
</blockquote>
<ol>
<li>
<p>在线转换</p>
<ul>
<li>简单来说就是写好了ES6了然后引用一个js库进来。我什么也不用做了。它替我去做了各种各样的事情</li>
<li>缺点,用户每次打开页面都要重新转换一遍,性能体验不是很好。</li>
</ul>
</li>
<li>提前编译</li>
</ol>
<p>ES6的到底有什么样的东西?</p>
<ol>
<li>变量(对原有的变量做了修改)</li>
<li>函数(对原有的函数也做了修改)</li>
<li><a href="http://www.js-code.com/tag/%e6%95%b0%e7%bb%84" title="数组" target="_blank">数组</a>(对<a href="http://www.js-code.com/tag/%e6%95%b0%e7%bb%84" title="数组" target="_blank">数组</a>做了一些改进)</li>
<li>字符串(改进)</li>
<li>面向对象</li>
<li><a href="http://www.js-code.com/tag/promis" title="Promis" target="_blank">Promis</a>e(串行化的异步请求方式)</li>
<li><a href="http://www.js-code.com/tag/yield" title="yield" target="_blank">yield</a> && generator(generator是专门把同步操作拆成异步操作,generator是对<a href="http://www.js-code.com/tag/promise" title="Promise" target="_blank">Promise</a>的一个封装)</li>
<li>模块化</li>
</ol>
<h2 id="articleHeader2">变量-<a href="http://www.js-code.com/tag/let" title="let" target="_blank">let</a>和<a href="http://www.js-code.com/tag/const" title="const" target="_blank">const</a></h2>
<p>回顾ES5是怎么生明变量的,有什么样的缺点</p>
<p><code><a href="http://www.js-code.com/tag/var" title="var" target="_blank">var</a></code>的缺点</p>
<ol>
<li>可以重复声明</li>
<li>无法限制修改</li>
<li>没有块级作用域</li>
</ol>
<p><strong>可以重复声明</strong></p>
<p>最大的问题</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="var a=12;
var a=5;
alert(a);//弹窗5" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">var</span> a=<span class="hljs-number">12</span>;
<span class="hljs-keyword">var</span> a=<span class="hljs-number">5</span>;
alert(a);<span class="hljs-comment">//弹窗5</span></code></pre>
<p>会发现5能出来,没有报错,没有警告,什么都没有</p>
<p>这在其他语言是不可出现的。</p>
<p><strong>无法限制修改</strong></p>
<p>在程序中,有些东西是永远不变的。</p>
<p>比方说常量<br /><code>PI=3.1415926</code><br />是不会发生改变<br />在很多语言中都有<code>常量</code>的概念。在js中没有</p>
<p>至少<code><a href="http://www.js-code.com/tag/var" title="var" target="_blank">var</a></code>不是一个常量。</p>
<p>换句话说,要不要改,能不能让别人别动这个值,不要改这个值。全凭自觉。</p>
<p>为什么<a href="http://www.js-code.com/tag/java" title="java" target="_blank">java</a>是全世界最流行的一门语言</p>
<p>原因很简单,因为他非常的严谨,他非常的死板。</p>
<p>相信一件事,越是容易的语言,越是简单的语言。实际上是不严谨。就没法去开发大型项目</p>
<p>反过来他可能让你觉得很难受的语言java,对你限制很严格。但是你掌握了呀之后,开发起大型应用会非常的得心应手。</p>
<p><strong>没有块级作用域</strong></p>
<p><a href="http://www.js-code.com/tag/es5" title="es5" target="_blank">es5</a> 只在函数中支持块级作用域</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="{
//这就是语法块
}
if(){
变量=xxxx
}
//变量出来就用不了了,这就是块作用域
for(){
}" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js">{
<span class="hljs-comment">//这就是语法块</span>
}
<span class="hljs-keyword">if</span>(){
变量=xxxx
}
<span class="hljs-comment">//变量出来就用不了了,这就是块作用域</span>
<span class="hljs-keyword">for</span>(){
}</code></pre>
<p>体现块级作用域作用</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="if(true){
var a=12;
}
alert(a);
//在块级作用域内声明变量。在外部依然能够访问" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">if</span>(<span class="hljs-literal">true</span>){
<span class="hljs-keyword">var</span> a=<span class="hljs-number">12</span>;
}
alert(a);
<span class="hljs-comment">//在块级作用域内声明变量。在外部依然能够访问</span></code></pre>
<p>在ES6中有了两种新的定义变量的方式</p>
<p><code><a href="http://www.js-code.com/tag/let" title="let" target="_blank">let</a></code>和<code><a href="http://www.js-code.com/tag/const" title="const" target="_blank">const</a></code></p>
<p><strong><a href="http://www.js-code.com/tag/let" title="let" target="_blank">let</a></strong></p>
<ul>
<li>不能重复声明,<a href="http://www.js-code.com/tag/let" title="let" target="_blank">let</a>是变量,可以修改,块级作用域</li>
<li>块级作用域</li>
<li>可修改let变量的值</li>
</ul>
<p><strong><a href="http://www.js-code.com/tag/const" title="const" target="_blank">const</a></strong></p>
<ul>
<li>不可重复声明,<a href="http://www.js-code.com/tag/const" title="const" target="_blank">const</a>常量,不能修改,块级作用域</li>
<li>块级作用域</li>
<li>不可修改const变量的值</li>
</ul>
<p><strong>let 不能重复声明例子</strong></p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let a=12;
let a=5;
console.log(a);
//报错
//Uncaught SyntaxError: Identifier 'a' has already been declared
//不能重复声明" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> a=<span class="hljs-number">12</span>;
<span class="hljs-keyword">let</span> a=<span class="hljs-number">5</span>;
<span class="hljs-built_in">console</span>.log(a);
<span class="hljs-comment">//报错</span>
<span class="hljs-comment">//Uncaught SyntaxError: Identifier 'a' has already been declared</span>
<span class="hljs-comment">//不能重复声明</span></code></pre>
<p><strong>const 不能重复声明例子</strong></p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="const a=12;
const a=5;
console.log(a);
//报错
//Uncaught SyntaxError: Identifier 'a' has already been declared
//不能重复声明" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">const</span> a=<span class="hljs-number">12</span>;
<span class="hljs-keyword">const</span> a=<span class="hljs-number">5</span>;
<span class="hljs-built_in">console</span>.log(a);
<span class="hljs-comment">//报错</span>
<span class="hljs-comment">//Uncaught SyntaxError: Identifier 'a' has already been declared</span>
<span class="hljs-comment">//不能重复声明</span></code></pre>
<p>在大型项目中,重复声明这件事,指不定你定义了什么东西别人也定义了。还不报错,到时候定位bug很难找。</p>
<p><strong>变量和常量</strong></p>
<p>变量</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let a=12;//声明变量赋值
a=5;//给变量a赋值
console.log(a);//你会明确的发现它变成了5" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> a=<span class="hljs-number">12</span>;<span class="hljs-comment">//声明变量赋值</span>
a=<span class="hljs-number">5</span>;<span class="hljs-comment">//给变量a赋值</span>
<span class="hljs-built_in">console</span>.log(a);<span class="hljs-comment">//你会明确的发现它变成了5</span></code></pre>
<p>常量</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="const a=12;
a=5;
console.log(a);" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">const</span> a=<span class="hljs-number">12</span>;
a=<span class="hljs-number">5</span>;
<span class="hljs-built_in">console</span>.log(a);</code></pre>
<p>报错,不能对常量赋值<br /><span class="img-wrap"><img data-src="http://blog.huanghanlian.com/uploads/article/9de51493-88ca-41e9-931a-3e60ecbca02e.png" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="继小鹏" title="继小鹏" style="cursor: pointer;"></span></p>
<p><strong>块级作用域</strong></p>
<p>var 块级作用域只在函数中体现,也就是说在函数中<code>var</code>声明的变量不会在全局作用域中体现</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function aa(){
var a=1;
console.log(a)
}
aa();
console.log(a)" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">aa</span>(<span class="hljs-params"></span>)</span>{
<span class="hljs-keyword">var</span> a=<span class="hljs-number">1</span>;
<span class="hljs-built_in">console</span>.log(a)
}
aa();
<span class="hljs-built_in">console</span>.log(a)</code></pre>
<p><span class="img-wrap"><img data-src="http://blog.huanghanlian.com/uploads/article/2ef2ac80-8ae7-4622-9a73-5e73f8125c68.png" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="继小鹏" title="继小鹏" style="cursor: pointer;"></span></p>
<p>let和const只在块级作用域,或者在语法块之内起作用</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="if(true){
let a=12;
}
console.log(a);//Uncaught ReferenceError: a is not defined" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">if</span>(<span class="hljs-literal">true</span>){
<span class="hljs-keyword">let</span> a=<span class="hljs-number">12</span>;
}
<span class="hljs-built_in">console</span>.log(a);<span class="hljs-comment">//Uncaught ReferenceError: a is not defined</span></code></pre>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="if(true){
const a=12;
}
console.log(a);//Uncaught ReferenceError: a is not defined" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">if</span>(<span class="hljs-literal">true</span>){
<span class="hljs-keyword">const</span> a=<span class="hljs-number">12</span>;
}
<span class="hljs-built_in">console</span>.log(a);<span class="hljs-comment">//Uncaught ReferenceError: a is not defined</span></code></pre>
<p>语言推出一个新的版本,一个更好的版本,他一定是要解决一些原来有的问题,ES6也不例外。</p>
<p><strong>块级作用域有什么</strong></p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="<a href="http://www.js-code.com/tag/button" title="button" target="_blank">button</a>" <a href="http://www.js-code.com/tag/class" title="class" target="_blank">class</a>="copyCode code-tool" data-toggle="tooltip" data-placement="<a href="http://www.js-code.com/tag/top" title="top" target="_blank">top</a>" data-clipboard-<a href="http://www.js-code.com/tag/text" title="text" target="_blank">text</a>="<!DOCTYPE html><br />
<html lang="en"><br />
<head><br />
<meta charset="UTF-8"><br />
<title>Document</title><br />
</head><br />
<body><br />
<input type="button" value="按钮1"><br />
<input type="button" value="按钮2"><br />
<input type="button" value="按钮3"><br />
</body><br />
<script type="text/javascript">
w<a href="http://www.js-code.com/tag/in" title="in" target="_blank">in</a><a href="http://www.js-code.com/tag/do" title="do" target="_blank">do</a>w.<a href="http://www.js-code.com/tag/onload" title="onload" target="_blank">onload</a>=<a href="http://www.js-code.com/tag/function" title="function" target="_blank">function</a>(){
var aBtn=<a href="http://www.js-code.com/tag/document" title="document" target="_blank">document</a>.getElementsByTagName('<a href="http://www.js-code.com/tag/in" title="in" target="_blank">in</a>put');
<a href="http://www.js-code.com/tag/for" title="for" target="_blank">for</a> (var i = 0; i < aBtn.<a href="http://www.js-code.com/tag/length" title="length" target="_blank">length</a>; i++) {
aBtn[i].<a href="http://www.js-code.com/tag/onclick" title="onclick" target="_blank">onclick</a>=<a href="http://www.js-code.com/tag/function" title="function" target="_blank">function</a>(){
<a href="http://www.js-code.com/tag/alert" title="alert" target="_blank">alert</a>(i)
};
}
};
</script><br />
</html>" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="xml hljs"><code class="html"><span class="hljs-meta"><!DOCTYPE html></span>
<span class="hljs-tag"><<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">head</span>></span>
<span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">title</span>></span>Document<span class="hljs-tag"></<span class="hljs-name">title</span>></span>
<span class="hljs-tag"></<span class="hljs-name">head</span>></span>
<span class="hljs-tag"><<span class="hljs-name">body</span>></span>
<span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"按钮1"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"按钮2"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"按钮3"</span>></span>
<span class="hljs-tag"></<span class="hljs-name">body</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/javascript"</span>></span><span class="javascript">
<span class="hljs-built_in">window</span>.onload=<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
<span class="hljs-keyword">var</span> aBtn=<span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">'input'</span>);
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < aBtn.length; i++) {
aBtn[i].onclick=<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
alert(i)
};
}
};
</span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"></<span class="hljs-name">html</span>></span></code></pre>
<p><span class="img-wrap"><img data-src="http://blog.huanghanlian.com/uploads/article/4f5101b1-10d9-4a19-9785-d3e9f295cfa0.png" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="继小鹏" title="继小鹏" style="cursor: pointer;"></span></p>
<p>以上代码执行,不管按哪个按钮弹出都是3</p>
<p>由于<code>var</code>声明变量只在函数作用域中扩散到全局</p>
<p>在<a href="http://www.js-code.com/tag/for" title="for" target="_blank">for</a>或者<a href="http://www.js-code.com/tag/if" title="if" target="_blank">if</a>快级作用域中声明的变量会在局部或全局生效</p>
<p>当<code>for</code>循环执行完毕,<code>i</code>这个变量暴露到全局了,等于3</p>
<p>所以<code>for</code>循环中执行的事件绑定,是将点击事件回调函数执行。当点击按钮时候,会出发绑定回调函数,此时当前作用域中,<code>i</code>等于3,所以无论点击哪个按钮弹出都是3</p>
<p>以前我们是通过闭包解决这个问题</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="<a href="http://www.js-code.com/tag/button" title="button" target="_blank">button</a>" <a href="http://www.js-code.com/tag/class" title="class" target="_blank">class</a>="copyCode code-tool" data-toggle="tooltip" data-placement="<a href="http://www.js-code.com/tag/top" title="top" target="_blank">top</a>" data-clipboard-<a href="http://www.js-code.com/tag/text" title="text" target="_blank">text</a>="<!DOCTYPE html><br />
<html lang="en"><br />
<head><br />
<meta charset="UTF-8"><br />
<title>Document</title><br />
</head><br />
<body><br />
<input type="button" value="按钮1"><br />
<input type="button" value="按钮2"><br />
<input type="button" value="按钮3"><br />
</body><br />
<script type="text/javascript">
<a href="http://www.js-code.com/tag/window" title="window" target="_blank">window</a>.<a href="http://www.js-code.com/tag/onload" title="onload" target="_blank">onload</a>=<a href="http://www.js-code.com/tag/function" title="function" target="_blank">function</a>(){
var aBtn=<a href="http://www.js-code.com/tag/do" title="do" target="_blank">do</a>cument.getElementsByTagName('input');
for (var i = 0; i < aBtn.<a href="http://www.js-code.com/tag/length" title="length" target="_blank">length</a>; i++) {
! <a href="http://www.js-code.com/tag/function" title="function" target="_blank">function</a>(i) {
aBtn[i].<a href="http://www.js-code.com/tag/onclick" title="onclick" target="_blank">onclick</a>=function(){
<a href="http://www.js-code.com/tag/alert" title="alert" target="_blank">alert</a>(i)
};
}(i);
}
console.log(i)
};
</script><br />
</html>" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="xml hljs"><code class="html"><span class="hljs-meta"><!DOCTYPE html></span>
<span class="hljs-tag"><<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">head</span>></span>
<span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">title</span>></span>Document<span class="hljs-tag"></<span class="hljs-name">title</span>></span>
<span class="hljs-tag"></<span class="hljs-name">head</span>></span>
<span class="hljs-tag"><<span class="hljs-name">body</span>></span>
<span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"按钮1"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"按钮2"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"按钮3"</span>></span>
<span class="hljs-tag"></<span class="hljs-name">body</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/javascript"</span>></span><span class="javascript">
<span class="hljs-built_in">window</span>.onload=<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
<span class="hljs-keyword">var</span> aBtn=<span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">'input'</span>);
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < aBtn.length; i++) {
! <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">i</span>) </span>{
aBtn[i].onclick=<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
alert(i)
};
}(i);
}
<span class="hljs-built_in">console</span>.log(i)
};
</span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"></<span class="hljs-name">html</span>></span></code></pre>
<p>在每一层循环的时候,用一个匿名函数而且是立即执行的匿名函数给他包装起来,然后将每一次遍历的1.2.3分别的值去传到这个匿名函数里,然后匿名函数接到这个参数i再放到点击事件中去引用i当我们每次点击事件输出的值i就会取每一个闭包环境下的i。所以这样就能达到效果。</p>
<p>使用<code>let</code>来实现</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="<!DOCTYPE html><br />
<html lang="en"><br />
<head><br />
<meta charset="UTF-8"><br />
<title>Document</title><br />
</head><br />
<body><br />
<input type="button" value="按钮1"><br />
<input type="button" value="按钮2"><br />
<input type="button" value="按钮3"><br />
</body><br />
<script type="text/javascript">
<a href="http://www.js-code.com/tag/window" title="window" target="_blank">window</a>.onload=function(){
var aBtn=<a href="http://www.js-code.com/tag/document" title="document" target="_blank">document</a>.getElementsByTagName('input');
for (let i = 0; i < aBtn.length; i++) {
aBtn[i].onclick=function(){
alert(i)
};
}
console.log(i)
};
</script><br />
</html>" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="xml hljs"><code class="html"><span class="hljs-meta"><!DOCTYPE html></span>
<span class="hljs-tag"><<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">head</span>></span>
<span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">title</span>></span>Document<span class="hljs-tag"></<span class="hljs-name">title</span>></span>
<span class="hljs-tag"></<span class="hljs-name">head</span>></span>
<span class="hljs-tag"><<span class="hljs-name">body</span>></span>
<span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"按钮1"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"按钮2"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"按钮3"</span>></span>
<span class="hljs-tag"></<span class="hljs-name">body</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/javascript"</span>></span><span class="javascript">
<span class="hljs-built_in">window</span>.onload=<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
<span class="hljs-keyword">var</span> aBtn=<span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">'input'</span>);
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i < aBtn.length; i++) {
aBtn[i].onclick=<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
alert(i)
};
}
<span class="hljs-built_in">console</span>.log(i)
};
</span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"></<span class="hljs-name">html</span>></span></code></pre>
<p><span class="img-wrap"><img data-src="http://blog.huanghanlian.com/uploads/article/c4c9f770-de40-4409-80de-e4a26d7baee2.png" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="继小鹏" title="继小鹏" style="cursor: pointer;"></span></p>
<p><code>for</code>循环本身就是一个语法块,自身就是一个块</p>
<p>由于<code>var</code>只把函数作为作用域</p>
<p>所以以上需要通过立即执行函数来包一层,来实现效果。</p>
<p>而<code>let</code>本身是支持块级作用域的,所以电脑按钮执行回掉函数,打印i,是当前块级作用域下的<code>i</code></p>
<p>这个<code>i</code>在非<code>for</code>块作用域下是未定义的。</p>
<h2 id="articleHeader3">函数-<a href="http://www.js-code.com/tag/%e7%ae%ad%e5%a4%b4%e5%87%bd%e6%95%b0" title="箭头函数" target="_blank">箭头函数</a></h2>
<p><strong><a href="http://www.js-code.com/tag/%e7%ae%ad%e5%a4%b4%e5%87%bd%e6%95%b0" title="箭头函数" target="_blank">箭头函数</a>在写法上对es5做了一些修整,代码看起来更显得简洁</strong></p>
<ul>
<li>如果只有一个参数,圆括号"()"可以省略</li>
<li>函数体如果只有一句<a href="http://www.js-code.com/tag/return" title="return" target="_blank">return</a>语句,花括号也可以省略</li>
</ul>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="// 定义一个箭头函数
let a = (arg)=>{ // 这里=>符号就相当于function关键字<br />
return arg+=1<br />
}<br />
// 也可以简写为<br />
let a = arg => arg+=1" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-comment">// 定义一个箭头函数</span>
<span class="hljs-keyword">let</span> a = <span class="hljs-function">(<span class="hljs-params">arg</span>)=></span>{ <span class="hljs-comment">// 这里=>符号就相当于function关键字</span>
<span class="hljs-keyword">return</span> arg+=<span class="hljs-number">1</span>
}
<span class="hljs-comment">// 也可以简写为</span>
<span class="hljs-keyword">let</span> a = <span class="hljs-function"><span class="hljs-params">arg</span> =></span> arg+=<span class="hljs-number">1</span></code></pre>
<p>箭头函数的作用跟以前接触的函数没什么本质的区别,更多的是一种写法上的变化。</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function show() {
}
同等于
let show =()=>{</p>
<p>}" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">show</span>(<span class="hljs-params"></span>) </span>{
}
同等于
<span class="hljs-keyword">let</span> show =<span class="hljs-function"><span class="hljs-params">()</span>=></span>{
}</code></pre>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function () {
}
同等于
()=>{</p>
<p>}" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
}
同等于
()=>{
}</code></pre>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="<!DOCTYPE html><br />
<html lang="en"><br />
<head><br />
<meta charset="UTF-8"><br />
<title>Document</title><br />
</head><br />
<body></p>
<p></body><br />
<script type="text/javascript">
window.onload=function(){
alert('123')
};
</script><br />
</html></p>
<p>同等于</p>
<p><!DOCTYPE html><br />
<html lang="en"><br />
<head><br />
<meta charset="UTF-8"><br />
<title>Document</title><br />
</head><br />
<body></p>
<p></body><br />
<script type="text/javascript">
window.onload=()=>{
alert('123')
};
</script><br />
</html>" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="xml hljs"><code class="html"><span class="hljs-meta"><!DOCTYPE html></span>
<span class="hljs-tag"><<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">head</span>></span>
<span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">title</span>></span>Document<span class="hljs-tag"></<span class="hljs-name">title</span>></span>
<span class="hljs-tag"></<span class="hljs-name">head</span>></span>
<span class="hljs-tag"><<span class="hljs-name">body</span>></span>
<span class="hljs-tag"></<span class="hljs-name">body</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/javascript"</span>></span><span class="javascript">
<span class="hljs-built_in">window</span>.onload=<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
alert(<span class="hljs-string">'123'</span>)
};
</span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"></<span class="hljs-name">html</span>></span>
同等于
<span class="hljs-meta"><!DOCTYPE html></span>
<span class="hljs-tag"><<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">head</span>></span>
<span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">title</span>></span>Document<span class="hljs-tag"></<span class="hljs-name">title</span>></span>
<span class="hljs-tag"></<span class="hljs-name">head</span>></span>
<span class="hljs-tag"><<span class="hljs-name">body</span>></span>
<span class="hljs-tag"></<span class="hljs-name">body</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/javascript"</span>></span><span class="javascript">
<span class="hljs-built_in">window</span>.onload=<span class="hljs-function"><span class="hljs-params">()</span>=></span>{
alert(<span class="hljs-string">'123'</span>)
};
</span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"></<span class="hljs-name">html</span>></span></code></pre>
<p><strong>箭头函数也对<a href="http://www.js-code.com/tag/this" title="this" target="_blank">this</a>的指向做了修整</strong> es6之前的函数的<a href="http://www.js-code.com/tag/this" title="this" target="_blank">this</a>指向调用函数时所在的对象,而箭头函数的<a href="http://www.js-code.com/tag/this" title="this" target="_blank">this</a>指向函数定义时所在的对象</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="//普通函数
var obj = {
say: function () {
setTimeout(function() {
console.log(this)
});
}
}
obj.say();//Window object" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-comment">//普通函数</span>
<span class="hljs-keyword">var</span> obj = {
<span class="hljs-attr">say</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>)
});
}
}
obj.say();<span class="hljs-comment">//Window object</span></code></pre>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="// 箭头函数
var obj = {
say: function () {
setTimeout(() => {<br />
console.log(this)<br />
});<br />
},<br />
test:123<br />
}<br />
obj.say(); // obj" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-comment">// 箭头函数</span>
<span class="hljs-keyword">var</span> obj = {
<span class="hljs-attr">say</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =></span> {
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>)
});
},
<span class="hljs-attr">test</span>:<span class="hljs-number">123</span>
}
obj.say(); <span class="hljs-comment">// obj</span></code></pre>
<h2 id="articleHeader4">函数-参数</h2>
<ol>
<li>参数扩展/数组展开</li>
<li><a href="http://www.js-code.com/tag/%e9%bb%98%e8%ae%a4%e5%8f%82%e6%95%b0" title="默认参数" target="_blank">默认参数</a></li>
</ol>
<p><strong>参数扩展</strong></p>
<ol>
<li>收集剩余参数</li>
</ol>
<p>ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用<a href="http://www.js-code.com/tag/arguments" title="arguments" target="_blank">arguments</a>对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function show (a,b,...args){
console.log(a);//1
console.log(b);//2
console.log(args);//[3,4,5,6]
}
show(1,2,3,4,5,6);" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">show</span> (<span class="hljs-params">a,b,...args</span>)</span>{
<span class="hljs-built_in">console</span>.log(a);<span class="hljs-comment">//1</span>
<span class="hljs-built_in">console</span>.log(b);<span class="hljs-comment">//2</span>
<span class="hljs-built_in">console</span>.log(args);<span class="hljs-comment">//[3,4,5,6]</span>
}
show(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>,<span class="hljs-number">6</span>);</code></pre>
<p>下面是一个 rest 参数代替<a href="http://www.js-code.com/tag/arguments" title="arguments" target="_blank">arguments</a>变量的例子。</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="// arguments变量的写法
function sortNumbers() {
return Array.prototype.slice.call(arguments).sort();
}
// rest参数的写法
const sortNumbers = (...numbers) => numbers.sort();" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-comment">// arguments变量的写法</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sortNumbers</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">return</span> <span class="hljs-built_in">Array</span>.prototype.slice.call(<span class="hljs-built_in">arguments</span>).sort();
}
<span class="hljs-comment">// rest参数的写法</span>
<span class="hljs-keyword">const</span> sortNumbers = <span class="hljs-function">(<span class="hljs-params">...numbers</span>) =></span> numbers.sort();</code></pre>
<ol>
<li>展开数组</li>
</ol>
<p>展开后的效果,跟直接把数组内容写在这一样</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let arr=[1,2,3];
console.log(1,2,3);
console.log(...arr);
//1,2,3同等于...arr" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> arr=[<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>];
<span class="hljs-built_in">console</span>.log(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>);
<span class="hljs-built_in">console</span>.log(...arr);
<span class="hljs-comment">//1,2,3同等于...arr</span></code></pre>
<p><span class="img-wrap"><img data-src="http://blog.huanghanlian.com/uploads/article/c1275fb7-8846-46d2-842b-ef55f5722ffc.png" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="继小鹏" title="继小鹏" style="cursor: pointer;"></span></p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function show(a,b,c){
console.log(a)
console.log(b)
console.log(c)
}
let arr=[1,2,3];
show(1,2,3);
show(...arr);
//1,2,3同等于...arr" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">show</span>(<span class="hljs-params">a,b,c</span>)</span>{
<span class="hljs-built_in">console</span>.log(a)
<span class="hljs-built_in">console</span>.log(b)
<span class="hljs-built_in">console</span>.log(c)
}
<span class="hljs-keyword">let</span> arr=[<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>];
show(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>);
show(...arr);
<span class="hljs-comment">//1,2,3同等于...arr</span></code></pre>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let arr1=[1,2,3];
let arr2=[4,5,6];
let arr=[...arr1,...arr2];
let arrS=[1,2,3,4,5,6];
//...arr1,写法,相当于将数组内容掏出来内容" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> arr1=[<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>];
<span class="hljs-keyword">let</span> arr2=[<span class="hljs-number">4</span>,<span class="hljs-number">5</span>,<span class="hljs-number">6</span>];
<span class="hljs-keyword">let</span> arr=[...arr1,...arr2];
<span class="hljs-keyword">let</span> arrS=[<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>,<span class="hljs-number">6</span>];
<span class="hljs-comment">//...arr1,写法,相当于将数组内容掏出来内容</span></code></pre>
<p><strong><a href="http://www.js-code.com/tag/%e9%bb%98%e8%ae%a4%e5%8f%82%e6%95%b0" title="默认参数" target="_blank">默认参数</a></strong></p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function show(a,b=5,c=6){
//我希望b,默认是5 不传的时候
//我希望c,默认是6 不传的时候
console.log(a,b,c);//1,2,6
}
show(1,2);" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">show</span>(<span class="hljs-params">a,b=<span class="hljs-number">5</span>,c=<span class="hljs-number">6</span></span>)</span>{
<span class="hljs-comment">//我希望b,默认是5 不传的时候</span>
<span class="hljs-comment">//我希望c,默认是6 不传的时候</span>
<span class="hljs-built_in">console</span>.log(a,b,c);<span class="hljs-comment">//1,2,6</span>
}
show(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>);</code></pre>
<h2 id="articleHeader5"><a href="http://www.js-code.com/tag/%e8%a7%a3%e6%9e%84%e8%b5%8b%e5%80%bc" title="解构赋值" target="_blank">解构赋值</a></h2>
<p>允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。比如:</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="var [a,b] = [1,2]
// a=1 b=2" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">var</span> [a,b] = [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>]
<span class="hljs-comment">// a=1 b=2</span></code></pre>
<ol>
<li>左右两边结构必须一样</li>
<li>右边必须是个合法的数据</li>
<li>声明和赋值必须一句话完成,不能把声明与赋值分开</li>
</ol>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let [a, b] = [1, 2] // 左右都是数组,可以解构赋值
let {a, b} = {a:1, b:2} // 左右都是对象,可以解构赋值
let [obj, arr] = [{a:1}, [1, 2]] // 左右都是对象,可以解构赋值
let [a, b] = {a:1, b:2} // err 左右结构不一样,不可以解构赋值
let {a,b} = {1, 2} // err 右边不是一个合法的数据,不能解构赋值
let [a, b];
[a, b] = [1, 2] // err 声明与赋值分开,不能解构赋值" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> [a, b] = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>] <span class="hljs-comment">// 左右都是数组,可以解构赋值</span>
<span class="hljs-keyword">let</span> {a, b} = {<span class="hljs-attr">a</span>:<span class="hljs-number">1</span>, <span class="hljs-attr">b</span>:<span class="hljs-number">2</span>} <span class="hljs-comment">// 左右都是对象,可以解构赋值</span>
<span class="hljs-keyword">let</span> [obj, arr] = [{<span class="hljs-attr">a</span>:<span class="hljs-number">1</span>}, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>]] <span class="hljs-comment">// 左右都是对象,可以解构赋值</span>
<span class="hljs-keyword">let</span> [a, b] = {<span class="hljs-attr">a</span>:<span class="hljs-number">1</span>, <span class="hljs-attr">b</span>:<span class="hljs-number">2</span>} <span class="hljs-comment">// err 左右结构不一样,不可以解构赋值</span>
<span class="hljs-keyword">let</span> {a,b} = {<span class="hljs-number">1</span>, <span class="hljs-number">2</span>} <span class="hljs-comment">// err 右边不是一个合法的数据,不能解构赋值</span>
<span class="hljs-keyword">let</span> [a, b];
[a, b] = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>] <span class="hljs-comment">// err 声明与赋值分开,不能解构赋值</span></code></pre>
<h2 id="articleHeader6">数组</h2>
<p>数组扩展了4个方法:map、reduce、filter、forEach</p>
<ol>
<li>map 映射</li>
</ol>
<p>通过指定函数处理数组的每个元素,并返回处理后的数组。<br />一个对一个</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="[12,58,99,86,45,91]
[不及格,不及格,及格,及格,不及格,及格]
//将数组映射成另一个数组" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js">[<span class="hljs-number">12</span>,<span class="hljs-number">58</span>,<span class="hljs-number">99</span>,<span class="hljs-number">86</span>,<span class="hljs-number">45</span>,<span class="hljs-number">91</span>]
[不及格,不及格,及格,及格,不及格,及格]
<span class="hljs-comment">//将数组映射成另一个数组</span></code></pre>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="[45,57,135,28]
//将用户id映射成对象
[
{name:'huang',role:1},
{name:'huang1',role:2},
{name:'huang2',role:3},
{name:'huang4',role:1}
]" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js">[<span class="hljs-number">45</span>,<span class="hljs-number">57</span>,<span class="hljs-number">135</span>,<span class="hljs-number">28</span>]
<span class="hljs-comment">//将用户id映射成对象</span>
[
{<span class="hljs-attr">name</span>:<span class="hljs-string">'huang'</span>,<span class="hljs-attr">role</span>:<span class="hljs-number">1</span>},
{<span class="hljs-attr">name</span>:<span class="hljs-string">'huang1'</span>,<span class="hljs-attr">role</span>:<span class="hljs-number">2</span>},
{<span class="hljs-attr">name</span>:<span class="hljs-string">'huang2'</span>,<span class="hljs-attr">role</span>:<span class="hljs-number">3</span>},
{<span class="hljs-attr">name</span>:<span class="hljs-string">'huang4'</span>,<span class="hljs-attr">role</span>:<span class="hljs-number">1</span>}
]</code></pre>
<p><strong>map例子</strong></p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let arr=[12,5,8];
//我想要将数组内容乘与2的结果
let result=arr.map(function(item){
console.log(item);
//需要将你要的内容返回出来
return item*2;
});
console.log(arr);//[12, 5, 8]
console.log(result);//[24, 10, 16]" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> arr=[<span class="hljs-number">12</span>,<span class="hljs-number">5</span>,<span class="hljs-number">8</span>];
<span class="hljs-comment">//我想要将数组内容乘与2的结果</span>
<span class="hljs-keyword">let</span> result=arr.map(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">item</span>)</span>{
<span class="hljs-built_in">console</span>.log(item);
<span class="hljs-comment">//需要将你要的内容返回出来</span>
<span class="hljs-keyword">return</span> item*<span class="hljs-number">2</span>;
});
<span class="hljs-built_in">console</span>.log(arr);<span class="hljs-comment">//[12, 5, 8]</span>
<span class="hljs-built_in">console</span>.log(result);<span class="hljs-comment">//[24, 10, 16]</span></code></pre>
<p>简写1</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let arr=[12,5,8];
//我想要将数组内容乘与2的结果
let result=arr.map(item=>{<br />
console.log(item);<br />
//需要将你要的内容返回出来<br />
return item*2;<br />
});<br />
console.log(arr);//[12, 5, 8]<br />
console.log(result);//[24, 10, 16]" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> arr=[<span class="hljs-number">12</span>,<span class="hljs-number">5</span>,<span class="hljs-number">8</span>];
<span class="hljs-comment">//我想要将数组内容乘与2的结果</span>
<span class="hljs-keyword">let</span> result=arr.map(<span class="hljs-function"><span class="hljs-params">item</span>=></span>{
<span class="hljs-built_in">console</span>.log(item);
<span class="hljs-comment">//需要将你要的内容返回出来</span>
<span class="hljs-keyword">return</span> item*<span class="hljs-number">2</span>;
});
<span class="hljs-built_in">console</span>.log(arr);<span class="hljs-comment">//[12, 5, 8]</span>
<span class="hljs-built_in">console</span>.log(result);<span class="hljs-comment">//[24, 10, 16]</span></code></pre>
<p>简写2</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let arr=[12,5,8];
//我想要将数组内容乘与2的结果
let result=arr.map(item=>item*2);</p>
<p>console.log(arr);//[12, 5, 8]<br />
console.log(result);//[24, 10, 16]" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> arr=[<span class="hljs-number">12</span>,<span class="hljs-number">5</span>,<span class="hljs-number">8</span>];
<span class="hljs-comment">//我想要将数组内容乘与2的结果</span>
<span class="hljs-keyword">let</span> result=arr.map(<span class="hljs-function"><span class="hljs-params">item</span>=></span>item*<span class="hljs-number">2</span>);
<span class="hljs-built_in">console</span>.log(arr);<span class="hljs-comment">//[12, 5, 8]</span>
<span class="hljs-built_in">console</span>.log(result);<span class="hljs-comment">//[24, 10, 16]</span></code></pre>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let arr=[12,58,99,86,45,91]
let result=arr.map(item=>item>=60?'及格':'不及格');</p>
<p>console.log(arr);//[12, 58, 99, 86, 45, 91]<br />
console.log(result);//["不及格", "不及格", "及格", "及格", "不及格", "及格"]" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> arr=[<span class="hljs-number">12</span>,<span class="hljs-number">58</span>,<span class="hljs-number">99</span>,<span class="hljs-number">86</span>,<span class="hljs-number">45</span>,<span class="hljs-number">91</span>]
<span class="hljs-keyword">let</span> result=arr.map(<span class="hljs-function"><span class="hljs-params">item</span>=></span>item>=<span class="hljs-number">60</span>?<span class="hljs-string">'及格'</span>:<span class="hljs-string">'不及格'</span>);
<span class="hljs-built_in">console</span>.log(arr);<span class="hljs-comment">//[12, 58, 99, 86, 45, 91]</span>
<span class="hljs-built_in">console</span>.log(result);<span class="hljs-comment">//["不及格", "不及格", "及格", "及格", "不及格", "及格"]</span></code></pre>
<ol>
<li>reduce 汇总</li>
</ol>
<p>将数组元素计算为一个值(从左到右)。<br />一堆出一个</p>
<p>算个总数</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let arr=[12,58,99,86,45,91]
/**
* [description]
* @param {[type]} (total,currentValue,index,arr [
* 初始值, 或者计算结束后的返回值。
* 当前元素
* 当前元素的索引
* 当前元素所属的数组对象。
* ]
* @return {[type]} [返回计算结果]
*/
let result=arr.reduce((total,currentValue,index,arr)=>{<br />
return total+currentValue;<br />
});<br />
console.log(result)//391" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> arr=[<span class="hljs-number">12</span>,<span class="hljs-number">58</span>,<span class="hljs-number">99</span>,<span class="hljs-number">86</span>,<span class="hljs-number">45</span>,<span class="hljs-number">91</span>]
<span class="hljs-comment">/**
* [description]
* @param {[type]} (total,currentValue,index,arr [
* 初始值, 或者计算结束后的返回值。
* 当前元素
* 当前元素的索引
* 当前元素所属的数组对象。
* ]
* @return {[type]} [返回计算结果]
*/</span>
<span class="hljs-keyword">let</span> result=arr.reduce(<span class="hljs-function">(<span class="hljs-params">total,currentValue,index,arr</span>)=></span>{
<span class="hljs-keyword">return</span> total+currentValue;
});
<span class="hljs-built_in">console</span>.log(result)<span class="hljs-comment">//391</span></code></pre>
<p>算个平均数</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let arr=[12,58,99,86,45,91]
/**
* [description]
* @param {[type]} (total,currentValue,index,arr [
* 初始值, 或者计算结束后的返回值。
* 当前元素
* 当前元素的索引
* 当前元素所属的数组对象。
* ]
* @return {[type]} [返回计算结果]
*/
let result=arr.reduce((total,currentValue,index,arr)=>{<br />
if(index!=arr.length-1){ //如果不是最后一次<br />
return total+currentValue; //求和<br />
}else{ //最后一次<br />
return (total+currentValue)/arr.length; //求和再除于长度个数<br />
}<br />
});<br />
console.log(result)//65.16666666666667" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> arr=[<span class="hljs-number">12</span>,<span class="hljs-number">58</span>,<span class="hljs-number">99</span>,<span class="hljs-number">86</span>,<span class="hljs-number">45</span>,<span class="hljs-number">91</span>]
<span class="hljs-comment">/**
* [description]
* @param {[type]} (total,currentValue,index,arr [
* 初始值, 或者计算结束后的返回值。
* 当前元素
* 当前元素的索引
* 当前元素所属的数组对象。
* ]
* @return {[type]} [返回计算结果]
*/</span>
<span class="hljs-keyword">let</span> result=arr.reduce(<span class="hljs-function">(<span class="hljs-params">total,currentValue,index,arr</span>)=></span>{
<span class="hljs-keyword">if</span>(index!=arr.length<span class="hljs-number">-1</span>){ <span class="hljs-comment">//如果不是最后一次</span>
<span class="hljs-keyword">return</span> total+currentValue; <span class="hljs-comment">//求和</span>
}<span class="hljs-keyword">else</span>{ <span class="hljs-comment">//最后一次</span>
<span class="hljs-keyword">return</span> (total+currentValue)/arr.length; <span class="hljs-comment">//求和再除于长度个数</span>
}
});
<span class="hljs-built_in">console</span>.log(result)<span class="hljs-comment">//65.16666666666667</span></code></pre>
<ol>
<li>filter 过滤器</li>
</ol>
<p>检测数值元素,并返回符合条件所有元素的数组。</p>
<p>定义和用法</p>
<p>filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。</p>
<p>注意: filter() 不会对空数组进行检测。</p>
<p>注意: filter() 不会改变原始数组。</p>
<p>需求,能被3整除的留下,不能的去除</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let arr=[12,58,99,86,45,91]
//需求,能被3整除的留下,不能的去除
/**
* [description]
* @param {[type]} (currentValue,index,arr [
* 当前元素的值
* 当前元素的索引值
* 当前元素属于的数组对象
* ]
* @return {[type]} [返回数组,包含了符合条件的所有元素。如果没有符合条件的元素则返回空数组。]
*/
let result=arr.filter((currentValue,index,arr)=>{<br />
if(currentValue%3==0){<br />
return true;<br />
}else{<br />
return false;<br />
}<br />
});<br />
console.log(result)//[12, 99, 45]" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> arr=[<span class="hljs-number">12</span>,<span class="hljs-number">58</span>,<span class="hljs-number">99</span>,<span class="hljs-number">86</span>,<span class="hljs-number">45</span>,<span class="hljs-number">91</span>]
<span class="hljs-comment">//需求,能被3整除的留下,不能的去除</span>
<span class="hljs-comment">/**
* [description]
* @param {[type]} (currentValue,index,arr [
* 当前元素的值
* 当前元素的索引值
* 当前元素属于的数组对象
* ]
* @return {[type]} [返回数组,包含了符合条件的所有元素。如果没有符合条件的元素则返回空数组。]
*/</span>
<span class="hljs-keyword">let</span> result=arr.filter(<span class="hljs-function">(<span class="hljs-params">currentValue,index,arr</span>)=></span>{
<span class="hljs-keyword">if</span>(currentValue%<span class="hljs-number">3</span>==<span class="hljs-number">0</span>){
<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
}<span class="hljs-keyword">else</span>{
<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
}
});
<span class="hljs-built_in">console</span>.log(result)<span class="hljs-comment">//[12, 99, 45]</span></code></pre>
<p>简写</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let arr=[12,58,99,86,45,91]
//需求,能被3整除的留下,不能的去除
/**
* [description]
* @param {[type]} (currentValue,index,arr [
* 当前元素的值
* 当前元素的索引值
* 当前元素属于的数组对象
* ]
* @return {[type]} [返回数组,包含了符合条件的所有元素。如果没有符合条件的元素则返回空数组。]
*/
let result=arr.filter((currentValue,index,arr)=>{<br />
return currentValue%3==0;<br />
});<br />
console.log(result)//[12, 99, 45]" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> arr=[<span class="hljs-number">12</span>,<span class="hljs-number">58</span>,<span class="hljs-number">99</span>,<span class="hljs-number">86</span>,<span class="hljs-number">45</span>,<span class="hljs-number">91</span>]
<span class="hljs-comment">//需求,能被3整除的留下,不能的去除</span>
<span class="hljs-comment">/**
* [description]
* @param {[type]} (currentValue,index,arr [
* 当前元素的值
* 当前元素的索引值
* 当前元素属于的数组对象
* ]
* @return {[type]} [返回数组,包含了符合条件的所有元素。如果没有符合条件的元素则返回空数组。]
*/</span>
<span class="hljs-keyword">let</span> result=arr.filter(<span class="hljs-function">(<span class="hljs-params">currentValue,index,arr</span>)=></span>{
<span class="hljs-keyword">return</span> currentValue%<span class="hljs-number">3</span>==<span class="hljs-number">0</span>;
});
<span class="hljs-built_in">console</span>.log(result)<span class="hljs-comment">//[12, 99, 45]</span></code></pre>
<p>再次简写</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let arr=[12,58,99,86,45,91]
let result=arr.filter(currentValue=>currentValue%3==0);<br />
console.log(result)//[12, 99, 45]" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> arr=[<span class="hljs-number">12</span>,<span class="hljs-number">58</span>,<span class="hljs-number">99</span>,<span class="hljs-number">86</span>,<span class="hljs-number">45</span>,<span class="hljs-number">91</span>]
<span class="hljs-keyword">let</span> result=arr.filter(<span class="hljs-function"><span class="hljs-params">currentValue</span>=></span>currentValue%<span class="hljs-number">3</span>==<span class="hljs-number">0</span>);
<span class="hljs-built_in">console</span>.log(result)<span class="hljs-comment">//[12, 99, 45]</span></code></pre>
<ol>
<li>forEach 循环(迭代)</li>
</ol>
<p>数组每个元素都执行一次回调函数。</p>
<p>forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。</p>
<p>注意: forEach() 对于空数组是不会执行回调函数的。</p>
<h2 id="articleHeader7">字符串</h2>
<ol>
<li>多了两个新方法</li>
<li><a href="http://www.js-code.com/tag/%e5%ad%97%e7%ac%a6%e4%b8%b2%e6%a8%a1%e6%9d%bf" title="字符串模板" target="_blank">字符串模板</a></li>
</ol>
<p><strong>多了两个新方法</strong></p>
<ul>
<li>startsWith() 表示参数字符串是否在原字符串的头部,返回布尔值</li>
</ul>
<p>startsWith应用</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let str='http://blog.huanghanlian.com'
if(str.startsWith('http://')){
console.log('普通网址');
}else if(str.startsWith('https://')){
console.log('加密网址');
}else if(str.startsWith('git://')){
console.log('git网址');
}else if(str.startsWith('svn://')){
console.log('svn网址');
}else{
console.log('其他')
}" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> str=<span class="hljs-string">'http://blog.huanghanlian.com'</span>
<span class="hljs-keyword">if</span>(str.startsWith(<span class="hljs-string">'http://'</span>)){
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'普通网址'</span>);
}<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(str.startsWith(<span class="hljs-string">'https://'</span>)){
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'加密网址'</span>);
}<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(str.startsWith(<span class="hljs-string">'git://'</span>)){
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'git网址'</span>);
}<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(str.startsWith(<span class="hljs-string">'svn://'</span>)){
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'svn网址'</span>);
}<span class="hljs-keyword">else</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'其他'</span>)
}</code></pre>
<ul>
<li>endsWith() 表示参数字符串是否在原字符串的尾部,返回布尔值</li>
</ul>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let str='http://blog.huanghanlian.com/sitemap.xml'
if(str.endsWith('.xml')){
console.log('网站地图');
}else if(str.endsWith('.jpg')){
console.log('图片');
}else if(str.endsWith('.txt')){
console.log('文本文件');
}else{
console.log('其他')
}
//网站地图" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> str=<span class="hljs-string">'http://blog.huanghanlian.com/sitemap.xml'</span>
<span class="hljs-keyword">if</span>(str.endsWith(<span class="hljs-string">'.xml'</span>)){
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'网站地图'</span>);
}<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(str.endsWith(<span class="hljs-string">'.jpg'</span>)){
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'图片'</span>);
}<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(str.endsWith(<span class="hljs-string">'.txt'</span>)){
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'文本文件'</span>);
}<span class="hljs-keyword">else</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'其他'</span>)
}
<span class="hljs-comment">//网站地图</span></code></pre>
<ul>
<li>includes() 表示是否在原字符串找到了参数字符串,返回布尔值</li>
</ul>
<p><strong><a href="http://www.js-code.com/tag/%e5%ad%97%e7%ac%a6%e4%b8%b2%e6%a8%a1%e6%9d%bf" title="字符串模板" target="_blank">字符串模板</a></strong></p>
<p><a href="http://www.js-code.com/tag/%e6%a8%a1%e6%9d%bf%e5%ad%97%e7%ac%a6%e4%b8%b2" title="模板字符串" target="_blank">模板字符串</a>有两个能力</p>
<ol>
<li>能直接把变量塞到字符串中去。</li>
<li>可以折行</li>
</ol>
<p>平常写字符串有两种写法,</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let str="abc";
let str2='efg';" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> str=<span class="hljs-string">"abc"</span>;
<span class="hljs-keyword">let</span> str2=<span class="hljs-string">'efg'</span>;</code></pre>
<p>一种是单引号,一种是双引号。在js里都能用。没什么区别</p>
<p>现在出来一种新的字符串</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let str=`abc`;" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js" style="word-break: break-word; white-space: initial;"><span class="hljs-keyword">let</span> str=<span class="hljs-string">`abc`</span>;</code></pre>
<p>这种符号叫反单引号</p>
<p>简单使用例子</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let a=12;
let str=`a${a}bc`;
console.log(str);//a12bc" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> a=<span class="hljs-number">12</span>;
<span class="hljs-keyword">let</span> str=<span class="hljs-string">`a<span class="hljs-subst">${a}</span>bc`</span>;
<span class="hljs-built_in">console</span>.log(str);<span class="hljs-comment">//a12bc</span></code></pre>
<p>反单引号中的美元符号带上花括号他的作用就是把变量直接塞进字符串里面去。</p>
<p>例子</p>
<p>以前字符串拼接</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let title='我是标题';
let content='我是内容';
let str='
<div class="wrap">
<h1>'+title+'</h1>
<p>'+content+'</p>
</p></div>
<p>';<br />
document.body.innerHTML=str;<br />
console.log(str);" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> title=<span class="hljs-string">'我是标题'</span>;
<span class="hljs-keyword">let</span> content=<span class="hljs-string">'我是内容'</span>;
<span class="hljs-keyword">let</span> str=<span class="hljs-string">'<div class="wrap">
<h1>'</span>+title+<span class="hljs-string">'</h1>
<p>'</span>+content+<span class="hljs-string">'</p>
</div>'</span>;
<span class="hljs-built_in">document</span>.body.innerHTML=str;
<span class="hljs-built_in">console</span>.log(str);</code></pre>
<p>有了字符串模板后的写法</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let title='我是标题';
let content='我是内容';
let str='
<div class="wrap">
<h1>'+title+'</h1>
<p>'+content+'</p>
</p></div>
<p>';</p>
<p>let str2=`</p>
<div class="wrap">
<h1>${title}</h1>
<p>${content}</p>
</p></div>
<p>`;<br />
document.body.innerHTML=str2;<br />
console.log(str2);" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> title=<span class="hljs-string">'我是标题'</span>;
<span class="hljs-keyword">let</span> content=<span class="hljs-string">'我是内容'</span>;
<span class="hljs-keyword">let</span> str=<span class="hljs-string">'<div class="wrap">
<h1>'</span>+title+<span class="hljs-string">'</h1>
<p>'</span>+content+<span class="hljs-string">'</p>
</div>'</span>;
<span class="hljs-keyword">let</span> str2=<span class="hljs-string">`<div class="wrap">
<h1><span class="hljs-subst">${title}</span></h1>
<p><span class="hljs-subst">${content}</span></p>
</div>`</span>;
<span class="hljs-built_in">document</span>.body.innerHTML=str2;
<span class="hljs-built_in">console</span>.log(str2);</code></pre>
<h2 id="articleHeader8">面向对象-基础</h2>
<p><strong>面向对象</strong></p>
<p>es5面向对象</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function User(name,pass){
this.name=name;
this.pass=pass;
}
//给这个类加原型方法
/**
* [showName 获取用户名]
* @return {[type]} [返回用户名]
*/
User.prototype.showName=function(){
console.log(this.name);
return this.name;
};
/**
* [showPass 获取用户密码]
* @return {[type]} [返回用户密码]
*/
User.prototype.showPass=function(){
console.log(this.pass);
return this.pass;
};
var ul=new User('黄继鹏','abc');
//调用类方法
ul.showName();//黄继鹏" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">User</span>(<span class="hljs-params">name,pass</span>)</span>{
<span class="hljs-keyword">this</span>.name=name;
<span class="hljs-keyword">this</span>.pass=pass;
}
<span class="hljs-comment">//给这个类加原型方法</span>
<span class="hljs-comment">/**
* [showName 获取用户名]
* @return {[type]} [返回用户名]
*/</span>
User.prototype.showName=<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.name);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.name;
};
<span class="hljs-comment">/**
* [showPass 获取用户密码]
* @return {[type]} [返回用户密码]
*/</span>
User.prototype.showPass=<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.pass);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.pass;
};
<span class="hljs-keyword">var</span> ul=<span class="hljs-keyword">new</span> User(<span class="hljs-string">'黄继鹏'</span>,<span class="hljs-string">'abc'</span>);
<span class="hljs-comment">//调用类方法</span>
ul.showName();<span class="hljs-comment">//黄继鹏</span></code></pre>
<p>这样写的缺点</p>
<ol>
<li>类和构造函数不分,</li>
<li>类散开了,先声明一个构造函数,然后对函数原型添加方法</li>
</ol>
<p>ES6 提供了更接近传统语言的写法,引入了 <a href="http://www.js-code.com/tag/class" title="Class" target="_blank">Class</a>(类)这个概念,作为对象的模板。通过class关键字,可以定义类。 先看如何定义一个class类:</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="class User {
constructor(name) { // 构造器,相当于es5中的构造函数
this.name = name // 实例属性
}
showName(){ // 定义类的方法,不能使用function关键字,不能使用逗号分隔
console.log(this.name)
}
}
var foo = new User('黄继鹏')
foo.showName();//黄继鹏" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> </span>{
<span class="hljs-keyword">constructor</span>(name) { <span class="hljs-comment">// 构造器,相当于es5中的构造函数</span>
<span class="hljs-keyword">this</span>.name = name <span class="hljs-comment">// 实例属性</span>
}
showName(){ <span class="hljs-comment">// 定义类的方法,不能使用function关键字,不能使用逗号分隔</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.name)
}
}
<span class="hljs-keyword">var</span> foo = <span class="hljs-keyword">new</span> User(<span class="hljs-string">'黄继鹏'</span>)
foo.showName();<span class="hljs-comment">//黄继鹏</span></code></pre>
<h3 id="articleHeader9">(1)<a href="http://www.js-code.com/tag/constructor" title="constructor" target="_blank">constructor</a></h3>
<ul>
<li>es6中class类专用的构造器,相当于之前定义的构造函数,每个类都必须有<a href="http://www.js-code.com/tag/constructor" title="constructor" target="_blank">constructor</a>,如果没有则自动添加一个空的constructor构造器。</li>
<li>创建实例的时候自动执行constructor函数</li>
<li>constructor中的<a href="http://www.js-code.com/tag/this" title="this" target="_blank">this</a>指向实例,并且默认返回<a href="http://www.js-code.com/tag/this" title="this" target="_blank">this</a>(实例)</li>
</ul>
<h3 id="articleHeader10">(2)class类的<a href="http://www.js-code.com/tag/prototype" title="prototype" target="_blank">prototype</a></h3>
<p>其实class的基本类型就是函数(<a href="http://www.js-code.com/tag/typeof" title="typeof" target="_blank">typeof</a> User = "function"),既然是函数,那么就会有<a href="http://www.js-code.com/tag/prototype" title="prototype" target="_blank">prototype</a>属性。</p>
<p>类的所有方法都是定义在prototype上</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="class User {
constructor() {
// ...
}
toString() {
// ...
}
toValue() {
// ...
}
}
User.toValue() // err User.toValue is not a function
User.prototype.toValue() // 可以调用toValue方法
// 等同于
User.prototype = {
constructor() {},
toString() {},
toValue() {},
};" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> </span>{
<span class="hljs-keyword">constructor</span>() {
<span class="hljs-comment">// ...</span>
}
toString() {
<span class="hljs-comment">// ...</span>
}
toValue() {
<span class="hljs-comment">// ...</span>
}
}
User.toValue() <span class="hljs-comment">// err User.toValue is not a function</span>
User.prototype.toValue() <span class="hljs-comment">// 可以调用toValue方法</span>
<span class="hljs-comment">// 等同于</span>
User.prototype = {
<span class="hljs-keyword">constructor</span>() {},
toString() {},
toValue() {},
};</code></pre>
<h3 id="articleHeader11">(3)类的实例</h3>
<ul>
<li>类的实例只能通过<a href="http://www.js-code.com/tag/new" title="new" target="_blank">new</a>来创建</li>
<li>除了静态方法,定义在类上的所有的方法都会被实例继承</li>
<li>除非定义在类的<a href="http://www.js-code.com/tag/this" title="this" target="_blank">this</a>对象上才是实例属性,否则都是定义在类的原型(prototype)上</li>
</ul>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="//定义类
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
var point = new Point(2, 3);
point.toString() // (2, 3)
point.hasOwnProperty('x') // true
point.hasOwnProperty('y') // true
point.hasOwnProperty('toString') // false
point.proto.hasOwnProperty('toString') // true" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-comment">//定义类</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Point</span> </span>{
<span class="hljs-keyword">constructor</span>(x, y) {
<span class="hljs-keyword">this</span>.x = x;
<span class="hljs-keyword">this</span>.y = y;
}
toString() {
<span class="hljs-keyword">return</span> <span class="hljs-string">'('</span> + <span class="hljs-keyword">this</span>.x + <span class="hljs-string">', '</span> + <span class="hljs-keyword">this</span>.y + <span class="hljs-string">')'</span>;
}
}
<span class="hljs-keyword">var</span> point = <span class="hljs-keyword">new</span> Point(<span class="hljs-number">2</span>, <span class="hljs-number">3</span>);
point.toString() <span class="hljs-comment">// (2, 3)</span>
point.hasOwnProperty(<span class="hljs-string">'x'</span>) <span class="hljs-comment">// true</span>
point.hasOwnProperty(<span class="hljs-string">'y'</span>) <span class="hljs-comment">// true</span>
point.hasOwnProperty(<span class="hljs-string">'toString'</span>) <span class="hljs-comment">// false</span>
point.proto.hasOwnProperty(<span class="hljs-string">'toString'</span>) <span class="hljs-comment">// true</span></code></pre>
<h3 id="articleHeader12">(4)静态方法</h3>
<p>如果在类中定义一个方法的前面加上<a href="http://www.js-code.com/tag/static" title="static" target="_blank">static</a>关键字,就表示定义一个静态方法,静态方法不会被实例继承,但会被子类继承,所以不能通过实例使用静态方法,而是通过类直接调用</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="class User {
constructor(name){
this.name = name
}
static show(){
console.log('123')
}
}
class VipUser extends User{}
VipUser.show() // 123
User.show() // 123
var foo = new User('foo')
foo.show() // foo.show is not a function" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> </span>{
<span class="hljs-keyword">constructor</span>(name){
<span class="hljs-keyword">this</span>.name = name
}
<span class="hljs-keyword">static</span> show(){
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'123'</span>)
}
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VipUser</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">User</span></span>{}
VipUser.show() <span class="hljs-comment">// 123</span>
User.show() <span class="hljs-comment">// 123</span>
<span class="hljs-keyword">var</span> foo = <span class="hljs-keyword">new</span> User(<span class="hljs-string">'foo'</span>)
foo.show() <span class="hljs-comment">// foo.show is not a function</span></code></pre>
<h3 id="articleHeader13">(5)静态属性</h3>
<ul>
<li>class的静态属性指的是 <a href="http://www.js-code.com/tag/class" title="Class" target="_blank">Class</a> 本身的属性,目前只能通过Class.propName定义静态属性</li>
<li>静态属性可以被子类继承,不会被实例继承</li>
</ul>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="class User{}
User.name = 'foo' // 为class定义一个静态属性
class VipUser extends User{}
console.log(VipUser.name) // foo
var foo = new User()
console.log(foo.name) // undefined" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span></span>{}
User.name = <span class="hljs-string">'foo'</span> <span class="hljs-comment">// 为class定义一个静态属性</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VipUser</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">User</span></span>{}
<span class="hljs-built_in">console</span>.log(VipUser.name) <span class="hljs-comment">// foo</span>
<span class="hljs-keyword">var</span> foo = <span class="hljs-keyword">new</span> User()
<span class="hljs-built_in">console</span>.log(foo.name) <span class="hljs-comment">// undefined</span></code></pre>
<h3 id="articleHeader14">(6)私有属性和私有方法</h3>
<p>es6是不支持私有属性和私有方法,但是日常需求可能会用到私有属性和私有方法,所以目前有一些提案,不过只是提案,尚未支持。</p>
<p><strong>类的继承</strong></p>
<p>ES5写法</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function User(name,pass){
this.name=name;
this.pass=pass;
}
User.prototype.showName=function(){
console.log(this.name);
};
/**
* [showPass 获取用户密码]
* @return {[type]} [返回用户密码]
*/
User.prototype.showPass=function(){
console.log(this.pass);
};
//继承user类
function aUser(name, pass, type) {
User.call(this, name, pass);
this.type = type;
};
aUser.prototype.showType = function() {
console.log(this.type);
};
var ul=new User('黄继鹏','abc');
ul.showName()//黄继鹏
var ull=new aUser('继小鹏','ccc','男');
ul.showName();//继小鹏
ull.showType();//男
//aUser继承类User类,并且有自己的方法" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">User</span>(<span class="hljs-params">name,pass</span>)</span>{
<span class="hljs-keyword">this</span>.name=name;
<span class="hljs-keyword">this</span>.pass=pass;
}
User.prototype.showName=<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.name);
};
<span class="hljs-comment">/**
* [showPass 获取用户密码]
* @return {[type]} [返回用户密码]
*/</span>
User.prototype.showPass=<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.pass);
};
<span class="hljs-comment">//继承user类</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">aUser</span>(<span class="hljs-params">name, pass, type</span>) </span>{
User.call(<span class="hljs-keyword">this</span>, name, pass);
<span class="hljs-keyword">this</span>.type = type;
};
aUser.prototype.showType = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.type);
};
<span class="hljs-keyword">var</span> ul=<span class="hljs-keyword">new</span> User(<span class="hljs-string">'黄继鹏'</span>,<span class="hljs-string">'abc'</span>);
ul.showName()<span class="hljs-comment">//黄继鹏</span>
<span class="hljs-keyword">var</span> ull=<span class="hljs-keyword">new</span> aUser(<span class="hljs-string">'继小鹏'</span>,<span class="hljs-string">'ccc'</span>,<span class="hljs-string">'男'</span>);
ul.showName();<span class="hljs-comment">//继小鹏</span>
ull.showType();<span class="hljs-comment">//男</span>
<span class="hljs-comment">//aUser继承类User类,并且有自己的方法</span></code></pre>
<p><strong>class通过<a href="http://www.js-code.com/tag/extends" title="extends" target="_blank">extends</a>关键字实现继承:</strong></p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="class User {
constructor(name){
this.name = name
}
show(){...}
}
class VipUser extends User{
constructor(vipName){ // 子类的构造器
super(vipName) // 调用父类的constructor。相当于User.prototype.constructor.call(this,vipName)
}
showVip(){...}
}
var v = new VipUser('foo') // 创建实例
v instanceof VipUser // v是子类VipUser的实例
v instanceof User // v还是父类User的实例" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> </span>{
<span class="hljs-keyword">constructor</span>(name){
<span class="hljs-keyword">this</span>.name = name
}
show(){...}
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VipUser</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">User</span></span>{
<span class="hljs-keyword">constructor</span>(vipName){ <span class="hljs-comment">// 子类的构造器</span>
<span class="hljs-keyword">super</span>(vipName) <span class="hljs-comment">// 调用父类的constructor。相当于User.prototype.constructor.call(this,vipName)</span>
}
showVip(){...}
}
<span class="hljs-keyword">var</span> v = <span class="hljs-keyword">new</span> VipUser(<span class="hljs-string">'foo'</span>) <span class="hljs-comment">// 创建实例</span>
v <span class="hljs-keyword">instanceof</span> VipUser <span class="hljs-comment">// v是子类VipUser的实例</span>
v <span class="hljs-keyword">instanceof</span> User <span class="hljs-comment">// v还是父类User的实例</span></code></pre>
<h3 id="articleHeader15">(1)<a href="http://www.js-code.com/tag/super" title="super" target="_blank">super</a></h3>
<p><a href="http://www.js-code.com/tag/super" title="super" target="_blank">super</a>可以当做函数使用,也可以当做对象使用。</p>
<p>当做函数使用<br /><a href="http://www.js-code.com/tag/super" title="super" target="_blank">super</a>作为函数调用时,代表父类的构造函数,就是在子类的构造器中执行父类的constructor函数以获取父类的this对象,因为子类没有自己的this对象,所以ES6规定子类必须在constructor中执行一次<a href="http://www.js-code.com/tag/super" title="super" target="_blank">super</a>函数。super()函数只能在子类的constructor中执行,不能在其他地方执行。</p>
<p>虽然super代表父类的构造器,但是super()在执行时内部的this指向子类,所以super()就相当于User.prototype.constructor.c<a href="http://www.js-code.com/tag/all" title="all" target="_blank">all</a>(this)。</p>
<p>当做对象使用<br />super可以作为对象调用父类的属性和方法,在子类的普通方法中,指向父类的原型对象(即User.prototype);在子类的静态方法中,指向父类。</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="class User {
constructor(){
this.x = 'hello'
}
show() {
return 2;
}
}
class VipUser extends User {
constructor() {
super();
console.log(super.show()); // 2 此时super指向User.prototype,相当于User.prototype.show()
console.log(super.x) // undefined 无法访问实例属性
}
}
let vip = new VipUser();
console.log(vip.x);//hello" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> </span>{
<span class="hljs-keyword">constructor</span>(){
<span class="hljs-keyword">this</span>.x = <span class="hljs-string">'hello'</span>
}
show() {
<span class="hljs-keyword">return</span> <span class="hljs-number">2</span>;
}
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VipUser</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">User</span> </span>{
<span class="hljs-keyword">constructor</span>() {
<span class="hljs-keyword">super</span>();
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">super</span>.show()); <span class="hljs-comment">// 2 此时super指向User.prototype,相当于User.prototype.show()</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">super</span>.x) <span class="hljs-comment">// undefined 无法访问实例属性</span>
}
}
<span class="hljs-keyword">let</span> vip = <span class="hljs-keyword">new</span> VipUser();
<span class="hljs-built_in">console</span>.log(vip.x);<span class="hljs-comment">//hello</span></code></pre>
<p>由于super对象在普通函数中使用super指向User.prototype,所以super只能访问父类的原型上的方法,没法访问父类的实例属性和实例方法。</p>
<p>ES6规定如果在子类中使用super对象调用父类的方法时,方法内部的this指向子类</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="class User {
constructor() {
this.x = 1
}
show() {
return this.x;
}
}
class VipUser extends User {
constructor() {
super();
this.x = 2
console.log(super.show()) // 2 此时show()方法内部的this指向子类,所以输出2,而不是1
}
}
let vip = new VipUser();" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> </span>{
<span class="hljs-keyword">constructor</span>() {
<span class="hljs-keyword">this</span>.x = <span class="hljs-number">1</span>
}
show() {
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.x;
}
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VipUser</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">User</span> </span>{
<span class="hljs-keyword">constructor</span>() {
<span class="hljs-keyword">super</span>();
<span class="hljs-keyword">this</span>.x = <span class="hljs-number">2</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">super</span>.show()) <span class="hljs-comment">// 2 此时show()方法内部的this指向子类,所以输出2,而不是1</span>
}
}
<span class="hljs-keyword">let</span> vip = <span class="hljs-keyword">new</span> VipUser();</code></pre>
<p>上述代码中虽然super.show()调用的是User.prototype.show(),但是由于通过super对象调用父类方法时,方法内部的this指向子类,所以super.show()相当于 super.show().c<a href="http://www.js-code.com/tag/all" title="all" target="_blank">all</a>(this),也就是User.prototype.show().call(this)</p>
<p>在子类的静态方法中super对象指向父类,而不是父类的原型(User.prototype)。</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="class User {
constructor() {
this.x = 1
}
static fn() {
console.log('父类静态方法')
}
}
class VipUser extends User {
constructor() {
super();
this.x = 2
}
static childFn() {
super.fn() // 相当于User.fn()
}
}
VipUser.childFn()" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> </span>{
<span class="hljs-keyword">constructor</span>() {
<span class="hljs-keyword">this</span>.x = <span class="hljs-number">1</span>
}
<span class="hljs-keyword">static</span> fn() {
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'父类静态方法'</span>)
}
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VipUser</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">User</span> </span>{
<span class="hljs-keyword">constructor</span>() {
<span class="hljs-keyword">super</span>();
<span class="hljs-keyword">this</span>.x = <span class="hljs-number">2</span>
}
<span class="hljs-keyword">static</span> childFn() {
<span class="hljs-keyword">super</span>.fn() <span class="hljs-comment">// 相当于User.fn()</span>
}
}
VipUser.childFn()</code></pre>
<h3 id="articleHeader16">(2)类的prototype和proto属性</h3>
<p>在es5中每一个对象都有proto属性,指向对应的构造函数的prototype属性。Class 作为构造函数的语法糖,同时有prototype属性和proto属性,因此同时存在两条继承链。</p>
<ul>
<li>子类的proto属性,表示构造函数的继承,总是指向父类。</li>
<li>子类prototype属性的proto属性,表示方法的继承,总是指向父类的prototype属性。</li>
</ul>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="class User {
}
class VipUser extends User {
}
VipUser.proto === User // true
VipUser.prototype.proto === User.prototype // true" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> </span>{
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VipUser</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">User</span> </span>{
}
VipUser.proto === User <span class="hljs-comment">// true</span>
VipUser.prototype.proto === User.prototype <span class="hljs-comment">// true</span></code></pre>
<h3 id="articleHeader17">(3)实例的proto属性</h3>
<p>子类实例的proto属性指向子类的原型(子类的prototype),子类实例的proto属性的proto属性指向父类的原型(父类的prototype)</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="class User {
}
class VipUser extends User {
}
var vip = new VipUser()
console.log(vip.proto === VipUser.prototype) // true
console.log(vip.proto.proto === User.prototype) // true" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> </span>{
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VipUser</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">User</span> </span>{
}
<span class="hljs-keyword">var</span> vip = <span class="hljs-keyword">new</span> VipUser()
<span class="hljs-built_in">console</span>.log(vip.proto === VipUser.prototype) <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(vip.proto.proto === User.prototype) <span class="hljs-comment">// true</span></code></pre>
<h2 id="articleHeader18">面向对象-应用</h2>
<p>面向对象应用---react</p>
<p>react介绍:</p>
<ol>
<li>组件化</li>
</ol>
<p>在react里一个组件就是一个class,</p>
<ol>
<li>依赖于<a href="http://www.js-code.com/tag/jsx" title="JSX" target="_blank">JSX</a></li>
</ol>
<p>jsx==<a href="http://www.js-code.com/tag/babel" title="babel" target="_blank">babel</a>==browser.js</p>
<hr>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="<!DOCTYPE html><br />
<html lang="en"><br />
<head><br />
<meta charset="UTF-8"><br />
<title></title><br />
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script><br />
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script><br />
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script><br />
<script type="text/babel">
let oDiv=document.getElementById('<a href="http://www.js-code.com/tag/div" title="div" target="_blank">div</a>1');
<a href="http://www.js-code.com/tag/react" title="React" target="_blank">React</a><a href="http://www.js-code.com/tag/dom" title="DOM" target="_blank">DOM</a>.render(
<span>123</span>,
oDiv
);
</script><br />
</head><br />
<body></p>
<div id="div1"></div>
<p></body><br />
</html>" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="xml hljs"><code class="html"><span class="hljs-meta"><!DOCTYPE html></span>
<span class="hljs-tag"><<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">head</span>></span>
<span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">title</span>></span><span class="hljs-tag"></<span class="hljs-name">title</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"</span>></span><span class="undefined"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"</span>></span><span class="undefined"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"</span>></span><span class="undefined"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/babel"</span>></span><span class="javascript">
<span class="hljs-keyword">let</span> oDiv=<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'div1'</span>);
ReactDOM.render(
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">span</span>></span>123<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>,
oDiv
);
</span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"></<span class="hljs-name">head</span>></span>
<span class="hljs-tag"><<span class="hljs-name">body</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"div1"</span>></span><span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"></<span class="hljs-name">body</span>></span>
<span class="hljs-tag"></<span class="hljs-name">html</span>></span></code></pre>
<p><span class="img-wrap"><img data-src="http://blog.huanghanlian.com/uploads/article/7b4b2500-2ee3-4899-9700-7c5103120c02.png" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="继小鹏" title="继小鹏" style="cursor: pointer;"></span></p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="<a href="http://www.js-code.com/tag/react" title="React" target="_blank">React</a><a href="http://www.js-code.com/tag/dom" title="DOM" target="_blank">DOM</a>.render(<br />
<span>123</span>,<br />
oDiv<br />
);" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js">ReactDOM.render(
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">span</span>></span>123<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>,
oDiv
);</code></pre>
<p>这种语法为什么会支持呢?</p>
<p>这个就是jsx和普通js最大的差别。</p>
<p>你可以认为jsx是普通js的<strong>扩展版本</strong></p>
<p>既然是扩展版本,那肯定会多出一些功能来。</p>
<p>如果不写引号,不是字符串同时长得像html,他就是可以要创建一个标签</p>
<p>切换搭配重点</p>
<p>react是一个基于组件</p>
<p>组件与class形式存在</p>
<p>我想写一个组件,作为一个组件是不是应该有一些基本的功能,比如我能被渲染,我有一些状态,我有生命周期,换句话说我现在不是从零开始写一个class,我需要很多基础的类的集成。</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="class Test extends React.Component{
}" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Test</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span></span>{
}</code></pre>
<p>类继承最大的意义在于一切不用从零开始</p>
<p>一个类需要有构造函数<code>constructor</code>.<br />作为继承类,在构造函数中需要继承父级的属性</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="<!DOCTYPE html><br />
<html lang="en"><br />
<head><br />
<meta charset="UTF-8"><br />
<title></title><br />
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script><br />
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script><br />
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script><br />
<script type="text/babel">
class Test <a href="http://www.js-code.com/tag/extends" title="extends" target="_blank">extends</a> React.Component{
//构造函数接到任何参数,都给继承父级类
constructor(...args){
super(...args);
}
render(){
<a href="http://www.js-code.com/tag/return" title="return" target="_blank">return</a> </p>
<div>hello world</div>
<p> }
}</p>
<p>let oDiv=document.getElementById('<a href="http://www.js-code.com/tag/div" title="div" target="_blank">div</a>1');
ReactDOM.render(
<Test>123</Test>,
oDiv
);
</script><br />
</head><br />
<body></p>
<div id="div1"></div>
<p></body><br />
</html>" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><!DOCTYPE html>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">head</span>></span>
<span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">title</span>></span><span class="hljs-tag"></<span class="hljs-name">title</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"</span>></span><span class="undefined"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"</span>></span><span class="undefined"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"</span>></span><span class="undefined"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/babel"</span>></span><span class="javascript">
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Test</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span></span>{
<span class="hljs-comment">//构造函数接到任何参数,都给继承父级类</span>
<span class="hljs-keyword">constructor</span>(...args){
<span class="hljs-keyword">super</span>(...args);
}
render(){
<span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag"><<span class="hljs-name">div</span>></span>hello world<span class="hljs-tag"></<span class="hljs-name">div</span>></span></span>
}
}
<span class="hljs-keyword">let</span> oDiv=<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'div1'</span>);
ReactDOM.render(
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">Test</span>></span>123<span class="hljs-tag"></<span class="hljs-name">Test</span>></span></span>,
oDiv
);
</span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"></<span class="hljs-name">head</span>></span>
<span class="hljs-tag"><<span class="hljs-name">body</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"div1"</span>></span><span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"></<span class="hljs-name">body</span>></span>
<span class="hljs-tag"></<span class="hljs-name">html</span>></span></span></code></pre>
<p><span class="img-wrap"><img data-src="https://upload-images.jianshu.io/upload_images/3877962-2fe58f387cebf496.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="image.png" title="image.png" style="cursor: pointer;"></span></p>
<p>组件套组件方法例子</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="<!DOCTYPE html><br />
<html lang="en"><br />
<head><br />
<meta charset="UTF-8"><br />
<title></title><br />
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script><br />
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script><br />
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script><br />
<script type="text/babel">
class Item extends React.Component{
//构造函数接到任何参数,都给继承父级类
constructor(...args){
super(...args);
}
render(){
<a href="http://www.js-code.com/tag/return" title="return" target="_blank">return</a> </p>
<div>{this.props.str}</div>
<p> }
}</p>
<p>class List extends React.Component{
//构造函数接到任何参数,都给继承父级类
constructor(...args){
super(...args);
}
render(){
/*//写法1
let aItem=[];
for(let i=0;i<this.props.arr.length;i++){
aItem.push(<Item key={i} str={this.props.arr[i]}></Item>);
}*/
/*// 写法2
let aItem=this.props.arr.map((str,index)=>{
<a href="http://www.js-code.com/tag/return" title="return" target="_blank">return</a> <Item key={index} str={str}></Item>
})
return </p>
<div>
{aItem}
</div>
<p>*/
// 写法3
return </p>
<div>
{
this.props.arr.map((str,index)=>{
return <Item key={index} str={str}></Item>
})
}
</div>
<p> }
}</p>
<p>let oDiv=document.getElementById('div1');
ReactDOM.render(
<List arr={['abc','efg','hij']}></List>,
oDiv
);
</script><br />
</head><br />
<body></p>
<div id="div1"></div>
<p></body><br />
</html>" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="xml hljs"><code class="html"><span class="hljs-meta"><!DOCTYPE html></span>
<span class="hljs-tag"><<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">head</span>></span>
<span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">title</span>></span><span class="hljs-tag"></<span class="hljs-name">title</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"</span>></span><span class="undefined"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"</span>></span><span class="undefined"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"</span>></span><span class="undefined"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/babel"</span>></span><span class="javascript">
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Item</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span></span>{
<span class="hljs-comment">//构造函数接到任何参数,都给继承父级类</span>
<span class="hljs-keyword">constructor</span>(...args){
<span class="hljs-keyword">super</span>(...args);
}
render(){
<span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag"><<span class="hljs-name">div</span>></span>{this.props.str}<span class="hljs-tag"></<span class="hljs-name">div</span>></span></span>
}
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">List</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span></span>{
<span class="hljs-comment">//构造函数接到任何参数,都给继承父级类</span>
<span class="hljs-keyword">constructor</span>(...args){
<span class="hljs-keyword">super</span>(...args);
}
render(){
<span class="hljs-comment">/*//写法1
let aItem=[];
for(let i=0;i<this.props.arr.length;i++){
aItem.push(<Item key={i} str={this.props.arr[i]}></Item>);
}*/</span>
<span class="hljs-comment">/*// 写法2
let aItem=this.props.arr.map((str,index)=>{
return <Item key={index} str={str}></Item>
})
return <div>
{aItem}
</div>*/</span>
<span class="hljs-comment">// 写法3</span>
<span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag"><<span class="hljs-name">div</span>></span>
{
this.props.arr.map((str,index)=>{
return <span class="hljs-tag"><<span class="hljs-name">Item</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span> <span class="hljs-attr">str</span>=<span class="hljs-string">{str}</span>></span><span class="hljs-tag"></<span class="hljs-name">Item</span>></span>
})
}
<span class="hljs-tag"></<span class="hljs-name">div</span>></span></span>
}
}
<span class="hljs-keyword">let</span> oDiv=<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'div1'</span>);
ReactDOM.render(
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">List</span> <span class="hljs-attr">arr</span>=<span class="hljs-string">{[</span>'<span class="hljs-attr">abc</span>','<span class="hljs-attr">efg</span>','<span class="hljs-attr">hij</span>']}></span><span class="hljs-tag"></<span class="hljs-name">List</span>></span></span>,
oDiv
);
</span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"></<span class="hljs-name">head</span>></span>
<span class="hljs-tag"><<span class="hljs-name">body</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"div1"</span>></span><span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"></<span class="hljs-name">body</span>></span>
<span class="hljs-tag"></<span class="hljs-name">html</span>></span></code></pre>
<h2 id="articleHeader19"><a href="http://www.js-code.com/tag/promis" title="Promis" target="_blank">Promis</a>e</h2>
<p><a href="http://www.js-code.com/tag/promise" title="Promise" target="_blank">Promise</a>的中文含义是<strong>承诺</strong></p>
<p>了解Promise之前。先来了解下同步异步</p>
<p>异步:操作之间没啥管系,同时进行多个操作<br />同步:同时只能做一件事</p>
<p>同步异步的优缺点</p>
<p>异步:代码更复杂<br />同步:代码简单</p>
<p>一个页面可能会有多个请求<br />比如淘宝网页,banner区域,侧边栏,导航栏,右侧栏,信息商品等<br />都是由镀铬接口异步请求组成</p>
<p>这就回造成代码逻辑复杂</p>
<p>按照以往前端ajax请求写法。一个请求成功后继续请求嵌套。逻辑会变得异常费劲</p>
<p>异步</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="$.ajax({
type: 'post',
url: '/api/banner',
success:function(result){
console.log('成功');
$.ajax({
type: 'post',
url: '/api/1',
success:function(result){
console.log('成功');
$.ajax({
type: 'post',
url: '/api/banner',
success:function(result){
console.log('成功');
$.ajax({
type: 'post',
url: '/api/banner',
success:function(result){
console.log('成功')
},
error:function(error){
console.log('失败')
},
})
},
error:function(error){
console.log('失败')
},
})
},
error:function(error){
console.log('失败')
},
})
},
error:function(error){
console.log('失败')
},
})" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js">$.ajax({
<span class="hljs-attr">type</span>: <span class="hljs-string">'post'</span>,
<span class="hljs-attr">url</span>: <span class="hljs-string">'/api/banner'</span>,
<span class="hljs-attr">success</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">result</span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'成功'</span>);
$.ajax({
<span class="hljs-attr">type</span>: <span class="hljs-string">'post'</span>,
<span class="hljs-attr">url</span>: <span class="hljs-string">'/api/1'</span>,
<span class="hljs-attr">success</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">result</span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'成功'</span>);
$.ajax({
<span class="hljs-attr">type</span>: <span class="hljs-string">'post'</span>,
<span class="hljs-attr">url</span>: <span class="hljs-string">'/api/banner'</span>,
<span class="hljs-attr">success</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">result</span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'成功'</span>);
$.ajax({
<span class="hljs-attr">type</span>: <span class="hljs-string">'post'</span>,
<span class="hljs-attr">url</span>: <span class="hljs-string">'/api/banner'</span>,
<span class="hljs-attr">success</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">result</span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'成功'</span>)
},
<span class="hljs-attr">error</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">error</span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'失败'</span>)
},
})
},
<span class="hljs-attr">error</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">error</span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'失败'</span>)
},
})
},
<span class="hljs-attr">error</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">error</span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'失败'</span>)
},
})
},
<span class="hljs-attr">error</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">error</span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'失败'</span>)
},
})</code></pre>
<p>同步</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="let banner_data=ajax_async('/banner');
let banner_data1=ajax_async('/banner1');
let banner_data2=ajax_async('/banner2');
let banner_data3=ajax_async('/banner3');
let banner_data4=ajax_async('/banner4');" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">let</span> banner_data=ajax_async(<span class="hljs-string">'/banner'</span>);
<span class="hljs-keyword">let</span> banner_data1=ajax_async(<span class="hljs-string">'/banner1'</span>);
<span class="hljs-keyword">let</span> banner_data2=ajax_async(<span class="hljs-string">'/banner2'</span>);
<span class="hljs-keyword">let</span> banner_data3=ajax_async(<span class="hljs-string">'/banner3'</span>);
<span class="hljs-keyword">let</span> banner_data4=ajax_async(<span class="hljs-string">'/banner4'</span>);</code></pre>
<p>你会发现异步处理性能好,用户体验好,但实际代码复杂</p>
<p>要是同步方式页面用户体验不好</p>
<p>这个时候幻想一下,我能不能像同步方式来写代码。也像异步一样请求数据。</p>
<p>Promise就能做到这个工作</p>
<p>Promise--消除异步操作</p>
<ul>
<li>用同步书写方式,来书写异步方法</li>
</ul>
<p>Promise如何使用</p>
<p>需要使用promise的时候,你需要<a href="http://www.js-code.com/tag/new" title="new" target="_blank">new</a>一个promise对象。</p>
<p>这个对象接收一个参数,是一个函数。<br />将异步的代码写在函数里</p>
<p>这个函数两个参数<br /><code>resolve</code><em>决心</em><br /><code>reject</code><em>拒绝</em></p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="//封装Promise ajax
let p=new Promise(function(resolve,reject){
//异步代码块
//resolve--成功了
//reject--失败了
$.ajax({
type: 'post',
dataType:'json',
url: '/api/banner',
success:function(result){
resolve(result);
},
error:function(error){
reject(error);
},
})
});
//使用Promise ajax封装
//当Promise调用有结果了就会调用then
//then有两个参数,都是函数,第一个是resolve,第二个是reject
p.then((result)=>{<br />
console.log(result);<br />
},(error)=>{<br />
console.log(error);<br />
})" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-comment">//封装Promise ajax</span>
<span class="hljs-keyword">let</span> p=<span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">resolve,reject</span>)</span>{
<span class="hljs-comment">//异步代码块</span>
<span class="hljs-comment">//resolve--成功了</span>
<span class="hljs-comment">//reject--失败了</span>
$.ajax({
<span class="hljs-attr">type</span>: <span class="hljs-string">'post'</span>,
<span class="hljs-attr">dataType</span>:<span class="hljs-string">'json'</span>,
<span class="hljs-attr">url</span>: <span class="hljs-string">'/api/banner'</span>,
<span class="hljs-attr">success</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">result</span>)</span>{
resolve(result);
},
<span class="hljs-attr">error</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">error</span>)</span>{
reject(error);
},
})
});
<span class="hljs-comment">//使用Promise ajax封装</span>
<span class="hljs-comment">//当Promise调用有结果了就会调用then</span>
<span class="hljs-comment">//then有两个参数,都是函数,第一个是resolve,第二个是reject</span>
p.then(<span class="hljs-function">(<span class="hljs-params">result</span>)=></span>{
<span class="hljs-built_in">console</span>.log(result);
},(error)=>{
<span class="hljs-built_in">console</span>.log(error);
})</code></pre>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function createPromise(url){
return new Promise(function(resolve,reject){
//异步代码块
//resolve--成功了
//reject--失败了
$.ajax({
type: 'post',
dataType:'json',
url,
success:function(result){
resolve(result);
},
error:function(error){
reject(error);
},
})
});
}
createPromise('./aa')
.then((res)=>{<br />
console.log(res)<br />
},(err)=>{<br />
console.log(err)<br />
})" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createPromise</span>(<span class="hljs-params">url</span>)</span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">resolve,reject</span>)</span>{
<span class="hljs-comment">//异步代码块</span>
<span class="hljs-comment">//resolve--成功了</span>
<span class="hljs-comment">//reject--失败了</span>
$.ajax({
<span class="hljs-attr">type</span>: <span class="hljs-string">'post'</span>,
<span class="hljs-attr">dataType</span>:<span class="hljs-string">'json'</span>,
url,
<span class="hljs-attr">success</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">result</span>)</span>{
resolve(result);
},
<span class="hljs-attr">error</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">error</span>)</span>{
reject(error);
},
})
});
}
createPromise(<span class="hljs-string">'./aa'</span>)
.then(<span class="hljs-function">(<span class="hljs-params">res</span>)=></span>{
<span class="hljs-built_in">console</span>.log(res)
},(err)=>{
<span class="hljs-built_in">console</span>.log(err)
})</code></pre>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function createPromise(url){
return new Promise(function(resolve,reject){
//异步代码块
//resolve--成功了
//reject--失败了
$.ajax({
type: 'post',
dataType:'json',
url,
success:function(result){
resolve(result);
},
error:function(error){
reject(error);
},
})
});
}
Promise.all([
createPromise('./aa'),
createPromise('./bb')
])
.then((res)=>{<br />
let [arr1,arr2]=res<br />
},(err)=>{<br />
console.log(err)<br />
})" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createPromise</span>(<span class="hljs-params">url</span>)</span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">resolve,reject</span>)</span>{
<span class="hljs-comment">//异步代码块</span>
<span class="hljs-comment">//resolve--成功了</span>
<span class="hljs-comment">//reject--失败了</span>
$.ajax({
<span class="hljs-attr">type</span>: <span class="hljs-string">'post'</span>,
<span class="hljs-attr">dataType</span>:<span class="hljs-string">'json'</span>,
url,
<span class="hljs-attr">success</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">result</span>)</span>{
resolve(result);
},
<span class="hljs-attr">error</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">error</span>)</span>{
reject(error);
},
})
});
}
<span class="hljs-built_in">Promise</span>.all([
createPromise(<span class="hljs-string">'./aa'</span>),
createPromise(<span class="hljs-string">'./bb'</span>)
])
.then(<span class="hljs-function">(<span class="hljs-params">res</span>)=></span>{
<span class="hljs-keyword">let</span> [arr1,arr2]=res
},(err)=>{
<span class="hljs-built_in">console</span>.log(err)
})</code></pre>
<h2 id="articleHeader20">generator-认识生成器函数</h2>
<p><strong>generator的作用</strong></p>
<p>generator-生成器</p>
<p>生成器是程序里面的一个概念,可以依靠它生成一堆东西</p>
<p><a href="http://www.js-code.com/tag/generator" title="Generator" target="_blank">Generator</a>可以理解为生成器,和普通函数没多大区别,普通函数是只要开始执行,就一直执行到底,而<a href="http://www.js-code.com/tag/generator" title="Generator" target="_blank">Generator</a>函数是中间可以停,搭配使用next函数继续执行。</p>
<p>生动的比喻</p>
<p>普通函数好比坐飞机,飞机起飞,不到目的地中途是不会降落的</p>
<p>Generator好比于出租车。可以随叫随停。停了再走,走了再停</p>
<h3 id="articleHeader21">(1)定义一个Generator函数</h3>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function * fn(){
alert('a')
yield
alert('b')
}
var f = fn()
f.next() // a
f.next() // b" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> * <span class="hljs-title">fn</span>(<span class="hljs-params"></span>)</span>{
alert(<span class="hljs-string">'a'</span>)
<span class="hljs-keyword">yield</span>
alert(<span class="hljs-string">'b'</span>)
}
<span class="hljs-keyword">var</span> f = fn()
f.next() <span class="hljs-comment">// a</span>
f.next() <span class="hljs-comment">// b</span></code></pre>
<p>直接调用Generator函数,是什么都不执行的,调用第一个next()才开始执行,一直执行到第一个<a href="http://www.js-code.com/tag/yield" title="yield" target="_blank">yield</a>停止,第二次调用next(),从第一个<a href="http://www.js-code.com/tag/yield" title="yield" target="_blank">yield</a>执行到第二个<a href="http://www.js-code.com/tag/yield" title="yield" target="_blank">yield</a>停止,依次类推</p>
<p>现在疑惑,在真实场景中,我为什么要让一个函数停呢?</p>
<p>刚才举个了出租车的例子,说白了,你为什么要让出租车司机停车,肯定是你有事情,你要去忙,或者要求拿什么东西,或者见什么朋友。<br />等你事情办完了,还再回来。</p>
<p>所以Generator特别适合一个场景。</p>
<p>比如说你要请求数据。请求数据不是瞬间就能回来的,这个时候就需要暂停,来等他结果过来。再继续执行下面的操作。</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="/**
* 普通函数在执行过程中需要请求得到结果再执行对应代码,就会出现代码嵌套再嵌套
*/
function 函数(){
代码...
ajax({
代码...
})
}
/**
* Generator函数可以让代码在那一步暂时暂停 拿到数据后再继续往下走
*/
function *函数(){
代码...
yiels ajax(xxx)
代码...
}" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-comment">/**
* 普通函数在执行过程中需要请求得到结果再执行对应代码,就会出现代码嵌套再嵌套
*/</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> 函数(<span class="hljs-params"></span>)</span>{
代码...
ajax({
代码...
})
}
<span class="hljs-comment">/**
* Generator函数可以让代码在那一步暂时暂停 拿到数据后再继续往下走
*/</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> *函数(<span class="hljs-params"></span>)</span>{
代码...
yiels ajax(xxx)
代码...
}</code></pre>
<p>Generator是怎么做到走走停停的?</p>
<p>其实本质是用Generator函数生成了一堆小函数</p>
<p>比方说fn函数</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function * fn(){
alert('a')
yield
alert('b')
}
var f = fn()
f.next() // a
f.next() // b" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> * <span class="hljs-title">fn</span>(<span class="hljs-params"></span>)</span>{
alert(<span class="hljs-string">'a'</span>)
<span class="hljs-keyword">yield</span>
alert(<span class="hljs-string">'b'</span>)
}
<span class="hljs-keyword">var</span> f = fn()
f.next() <span class="hljs-comment">// a</span>
f.next() <span class="hljs-comment">// b</span></code></pre>
<p>其实他在背后生成了两个小函数</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function fn_1(){
alert('a')
}
function fn_2(){
alert('b')
}" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fn_1</span>(<span class="hljs-params"></span>)</span>{
alert(<span class="hljs-string">'a'</span>)
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fn_2</span>(<span class="hljs-params"></span>)</span>{
alert(<span class="hljs-string">'b'</span>)
}</code></pre>
<p>当然这个过程我们是看不见的<br />相当于把一个大函数切分成了两个小函数</p>
<p>第一次next的时候他走的是<code>fn_1</code></p>
<p>第二次next的时候走的是<code>fn_2</code></p>
<h3 id="articleHeader22">generator-yield</h3>
<p><strong>yield和next</strong></p>
<p>yield代表暂时暂停执行,next代表继续执行。</p>
<p>yield和next可以传参数,也可以有返回值</p>
<ol>
<li>yield可以传参</li>
</ol>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function *show(){
console.log('a')
let a=yield;
console.log('b')
console.log(a)
}
let gen=show();
gen.next(12)
gen.next(5)
//a
//b
//5" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> *<span class="hljs-title">show</span>(<span class="hljs-params"></span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'a'</span>)
<span class="hljs-keyword">let</span> a=<span class="hljs-keyword">yield</span>;
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'b'</span>)
<span class="hljs-built_in">console</span>.log(a)
}
<span class="hljs-keyword">let</span> gen=show();
gen.next(<span class="hljs-number">12</span>)
gen.next(<span class="hljs-number">5</span>)
<span class="hljs-comment">//a</span>
<span class="hljs-comment">//b</span>
<span class="hljs-comment">//5</span></code></pre>
<p><span class="img-wrap"><img data-src="http://blog.huanghanlian.com/uploads/article/4ef5cdb2-44ec-4e21-9baf-1ba63c4d0777.png" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="继小鹏" title="继小鹏" style="cursor: pointer;"></span></p>
<p>第一次执行next的时候执行黄色框代码<br />第二次执行红色框的代码</p>
<p>传参的时候通过yield来传参的时候,第一个next是无效的,<br />如果想给第一个过程传参需要使用传统方法,在使用函数时传参</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function *show(num1,num2){
console.log(`${num1},${num2}`)
console.log('a')
let a=yield;
console.log('b')
console.log(a)
}
let gen=show(11,12);
gen.next(12);//没法给yield传参
gen.next(5)
//11,12
//a
//b
//5" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> *<span class="hljs-title">show</span>(<span class="hljs-params">num1,num2</span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${num1}</span>,<span class="hljs-subst">${num2}</span>`</span>)
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'a'</span>)
<span class="hljs-keyword">let</span> a=<span class="hljs-keyword">yield</span>;
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'b'</span>)
<span class="hljs-built_in">console</span>.log(a)
}
<span class="hljs-keyword">let</span> gen=show(<span class="hljs-number">11</span>,<span class="hljs-number">12</span>);
gen.next(<span class="hljs-number">12</span>);<span class="hljs-comment">//没法给yield传参</span>
gen.next(<span class="hljs-number">5</span>)
<span class="hljs-comment">//11,12</span>
<span class="hljs-comment">//a</span>
<span class="hljs-comment">//b</span>
<span class="hljs-comment">//5</span></code></pre>
<ol>
<li>yield返回</li>
</ol>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function *show(){
console.log('a')
let a=yield 12;
console.log('b')
}
let gen=show(11,12);
let res1=gen.next();
console.log(res1)
let res2=gen.next()
console.log(res2)
//a
//{value: 12, done: false}
//b
//{value: undefined, done: true}" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> *<span class="hljs-title">show</span>(<span class="hljs-params"></span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'a'</span>)
<span class="hljs-keyword">let</span> a=<span class="hljs-keyword">yield</span> <span class="hljs-number">12</span>;
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'b'</span>)
}
<span class="hljs-keyword">let</span> gen=show(<span class="hljs-number">11</span>,<span class="hljs-number">12</span>);
<span class="hljs-keyword">let</span> res1=gen.next();
<span class="hljs-built_in">console</span>.log(res1)
<span class="hljs-keyword">let</span> res2=gen.next()
<span class="hljs-built_in">console</span>.log(res2)
<span class="hljs-comment">//a</span>
<span class="hljs-comment">//{value: 12, done: false}</span>
<span class="hljs-comment">//b</span>
<span class="hljs-comment">//{value: undefined, done: true}</span></code></pre>
<p>value是yield 返回的参数<br />done代码函数是否走完</p>
<p>为什么第二次执行完value是空</p>
<p>因为第二次next是执行的最后一道程序,最后一道程序就没有yield 了,如果想返回东西需要使用return</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function *show(){
console.log('a')
let a=yield 12;
console.log('b')
return 111;
}
let gen=show(11,12);
let res1=gen.next();
console.log(res1)
let res2=gen.next()
console.log(res2)
//a
//{value: 12, done: false}
//b
//{value: 111, done: true}" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> *<span class="hljs-title">show</span>(<span class="hljs-params"></span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'a'</span>)
<span class="hljs-keyword">let</span> a=<span class="hljs-keyword">yield</span> <span class="hljs-number">12</span>;
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'b'</span>)
<span class="hljs-keyword">return</span> <span class="hljs-number">111</span>;
}
<span class="hljs-keyword">let</span> gen=show(<span class="hljs-number">11</span>,<span class="hljs-number">12</span>);
<span class="hljs-keyword">let</span> res1=gen.next();
<span class="hljs-built_in">console</span>.log(res1)
<span class="hljs-keyword">let</span> res2=gen.next()
<span class="hljs-built_in">console</span>.log(res2)
<span class="hljs-comment">//a</span>
<span class="hljs-comment">//{value: 12, done: false}</span>
<span class="hljs-comment">//b</span>
<span class="hljs-comment">//{value: 111, done: true}</span></code></pre>
<p><strong>yield 到底是个啥</strong></p>
<p><span class="img-wrap"><img data-src="http://blog.huanghanlian.com/uploads/article/f4d969cf-b865-4087-8dd3-7514e9d72bbe.png" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="继小鹏" title="继小鹏" style="cursor: pointer;"></span></p>
<p><span class="img-wrap"><img data-src="http://blog.huanghanlian.com/uploads/article/858c5682-376c-420f-8e5f-1fa594b4f2dc.png" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="继小鹏" title="继小鹏" style="cursor: pointer;"></span></p>
<h3 id="articleHeader23">generator-实例:runner</h3>
<p>这种Generator函数适用多个异步请求之间有逻辑分析的情况,比如有一个需求,先请求用户数据,根据用户数据的类型判断用户是普通用户还是VIP用户,然后再根据判断结果请求普通商品数据或者VIP商品数据</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="// 借助runner脚本,runner脚本规定Generator函数执行完一个next之后自动执行下一个next
runner(function() * (){
let userData = yield $.ajax(...) // 请求用户数据
if(userData.type === 'vip') {
let goods = yield $.ajax(...) // 请求vip商品数据
} else {
let goods = yield $.ajax(...) // 请求普通商品数据
}
})" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-comment">// 借助runner脚本,runner脚本规定Generator函数执行完一个next之后自动执行下一个next</span>
runner(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) * (<span class="hljs-params"></span>)</span>{
<span class="hljs-keyword">let</span> userData = <span class="hljs-keyword">yield</span> $.ajax(...) <span class="hljs-comment">// 请求用户数据</span>
<span class="hljs-keyword">if</span>(userData.type === <span class="hljs-string">'vip'</span>) {
<span class="hljs-keyword">let</span> goods = <span class="hljs-keyword">yield</span> $.ajax(...) <span class="hljs-comment">// 请求vip商品数据</span>
} <span class="hljs-keyword">else</span> {
<span class="hljs-keyword">let</span> goods = <span class="hljs-keyword">yield</span> $.ajax(...) <span class="hljs-comment">// 请求普通商品数据</span>
}
})</code></pre>
<p><span class="img-wrap"><img data-src="http://blog.huanghanlian.com/uploads/article/2a1f856d-7ba3-40a9-9c5f-a761ccf5f860.png" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="继小鹏" title="继小鹏" style="cursor: pointer;"></span></p>
<p>第一次yield ajax其实是Promise对象,将Promise对象yield 出去。<br />yield 给了runner对象</p>
<p>将数据请求完成给data1</p>
<p>这个函数暂停了</p>
<p>使用Generator函数使得代码看起来更像同步代码,其实使用Promise同样可以实现这种效果,只不过得需要在then()函数中嵌套请求。</p>
<p><strong>异步请求的几种方式</strong></p>
<ol>
<li>回调写法</li>
</ol>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="$.ajax({
type: 'post',
url: '/api/banner',
success:function(result){
console.log('成功');
$.ajax({
type: 'post',
url: '/api/1',
success:function(result){
console.log('成功');
$.ajax({
type: 'post',
url: '/api/banner',
success:function(result){
console.log('成功');
$.ajax({
type: 'post',
url: '/api/banner',
success:function(result){
console.log('成功')
},
error:function(error){
console.log('失败')
},
})
},
error:function(error){
console.log('失败')
},
})
},
error:function(error){
console.log('失败')
},
})
},
error:function(error){
console.log('失败')
},
})" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js">$.ajax({
<span class="hljs-attr">type</span>: <span class="hljs-string">'post'</span>,
<span class="hljs-attr">url</span>: <span class="hljs-string">'/api/banner'</span>,
<span class="hljs-attr">success</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">result</span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'成功'</span>);
$.ajax({
<span class="hljs-attr">type</span>: <span class="hljs-string">'post'</span>,
<span class="hljs-attr">url</span>: <span class="hljs-string">'/api/1'</span>,
<span class="hljs-attr">success</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">result</span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'成功'</span>);
$.ajax({
<span class="hljs-attr">type</span>: <span class="hljs-string">'post'</span>,
<span class="hljs-attr">url</span>: <span class="hljs-string">'/api/banner'</span>,
<span class="hljs-attr">success</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">result</span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'成功'</span>);
$.ajax({
<span class="hljs-attr">type</span>: <span class="hljs-string">'post'</span>,
<span class="hljs-attr">url</span>: <span class="hljs-string">'/api/banner'</span>,
<span class="hljs-attr">success</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">result</span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'成功'</span>)
},
<span class="hljs-attr">error</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">error</span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'失败'</span>)
},
})
},
<span class="hljs-attr">error</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">error</span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'失败'</span>)
},
})
},
<span class="hljs-attr">error</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">error</span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'失败'</span>)
},
})
},
<span class="hljs-attr">error</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">error</span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'失败'</span>)
},
})</code></pre>
<ol>
<li>Promise写法</li>
</ol>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function createPromise(url){
return new Promise(function(resolve,reject){
//异步代码块
//resolve--成功了
//reject--失败了
$.ajax({
type: 'post',
dataType:'json',
url,
success:function(result){
resolve(result);
},
error:function(error){
reject(error);
},
})
});
}
Promise.all([
createPromise('./aa'),
createPromise('./bb')
])
.then((res)=>{<br />
let [arr1,arr2]=res<br />
},(err)=>{<br />
console.log(err)<br />
})" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createPromise</span>(<span class="hljs-params">url</span>)</span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">resolve,reject</span>)</span>{
<span class="hljs-comment">//异步代码块</span>
<span class="hljs-comment">//resolve--成功了</span>
<span class="hljs-comment">//reject--失败了</span>
$.ajax({
<span class="hljs-attr">type</span>: <span class="hljs-string">'post'</span>,
<span class="hljs-attr">dataType</span>:<span class="hljs-string">'json'</span>,
url,
<span class="hljs-attr">success</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">result</span>)</span>{
resolve(result);
},
<span class="hljs-attr">error</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">error</span>)</span>{
reject(error);
},
})
});
}
<span class="hljs-built_in">Promise</span>.all([
createPromise(<span class="hljs-string">'./aa'</span>),
createPromise(<span class="hljs-string">'./bb'</span>)
])
.then(<span class="hljs-function">(<span class="hljs-params">res</span>)=></span>{
<span class="hljs-keyword">let</span> [arr1,arr2]=res
},(err)=>{
<span class="hljs-built_in">console</span>.log(err)
})</code></pre>
<ol>
<li>Generator写法</li>
</ol>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="runner(function() * (){
let userData = yield $.ajax(...) // 请求用户数据
if(userData.type === 'vip') {
let goods = yield $.ajax(...) // 请求vip商品数据
} else {
let goods = yield $.ajax(...) // 请求普通商品数据
}
})" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js">runner(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) * (<span class="hljs-params"></span>)</span>{
<span class="hljs-keyword">let</span> userData = <span class="hljs-keyword">yield</span> $.ajax(...) <span class="hljs-comment">// 请求用户数据</span>
<span class="hljs-keyword">if</span>(userData.type === <span class="hljs-string">'vip'</span>) {
<span class="hljs-keyword">let</span> goods = <span class="hljs-keyword">yield</span> $.ajax(...) <span class="hljs-comment">// 请求vip商品数据</span>
} <span class="hljs-keyword">else</span> {
<span class="hljs-keyword">let</span> goods = <span class="hljs-keyword">yield</span> $.ajax(...) <span class="hljs-comment">// 请求普通商品数据</span>
}
})</code></pre>
<p>Promise和Generator相比,Generator并没有特别的省事</p>
<p>Promise也有它不适用的地方。我如果是写死要请求接口。那么Promise和Generator确实没太大区别,</p>
<p>Generator他的优点在于适合参杂一些逻辑</p>
<p>比方说在请求一个接口拿到用户信息,根据信息判断他该去请求哪些不同的接口</p>
<p><span class="img-wrap"><img data-src="http://blog.huanghanlian.com/uploads/article/7d3a11cb-d5b8-4cd0-8256-6de33532acd7.png" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="继小鹏" title="继小鹏" style="cursor: pointer;"></span></p>
<p>感觉比普通嵌套还麻烦</p>
<p>带逻辑-Generator</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="// 借助runner脚本,runner脚本规定Generator函数执行完一个next之后自动执行下一个next
runner(function() * (){
let userData = yield $.ajax(...) // 请求用户数据
if(userData.type === 'vip') {
let goods = yield $.ajax(...) // 请求vip商品数据
} else {
let goods = yield $.ajax(...) // 请求普通商品数据
}
})" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-comment">// 借助runner脚本,runner脚本规定Generator函数执行完一个next之后自动执行下一个next</span>
runner(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) * (<span class="hljs-params"></span>)</span>{
<span class="hljs-keyword">let</span> userData = <span class="hljs-keyword">yield</span> $.ajax(...) <span class="hljs-comment">// 请求用户数据</span>
<span class="hljs-keyword">if</span>(userData.type === <span class="hljs-string">'vip'</span>) {
<span class="hljs-keyword">let</span> goods = <span class="hljs-keyword">yield</span> $.ajax(...) <span class="hljs-comment">// 请求vip商品数据</span>
} <span class="hljs-keyword">else</span> {
<span class="hljs-keyword">let</span> goods = <span class="hljs-keyword">yield</span> $.ajax(...) <span class="hljs-comment">// 请求普通商品数据</span>
}
})</code></pre>
<p>Promise适合一次请求一堆场景<br />Generator适合逻辑性请求处理</p>
<h3 id="articleHeader24">generator-实例:KOA</h3>
<p>KOA是<a href="http://www.js-code.com/tag/node" title="node" target="_blank">node</a>js的框架</p>
<p><span class="img-wrap"><img data-src="http://blog.huanghanlian.com/uploads/article/46a51209-a30f-4de9-9fbf-ab049417173c.png" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="继小鹏" title="继小鹏" style="cursor: pointer;"></span></p>
<h2 id="articleHeader25">async await</h2>
<p>async其实就是对Generator的封装,只不过async可以自动执行next()。</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="async function read () {
let data1= await new Promise(resolve => {<br />
resolve('100')<br />
})<br />
let data2 = await 200</p>
<p>return 300<br />
}" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">read</span> (<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">let</span> data1= <span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-params">resolve</span> =></span> {
resolve(<span class="hljs-string">'100'</span>)
})
<span class="hljs-keyword">let</span> data2 = <span class="hljs-keyword">await</span> <span class="hljs-number">200</span>
<span class="hljs-keyword">return</span> <span class="hljs-number">300</span>
}</code></pre>
<h3 id="articleHeader26">async 返回值</h3>
<p>async默认返回一个Promise,如果return不是一个Promise对象,就会被转为立即resolve的Promise,可以在then函数中获取返回值。</p>
<p>async必须等到里面所有的await执行完,async才开始return,返回的Promise状态才改变。除非遇到return和错误。</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="async function fn () {
await 100
await 200
return 300
}
fn().then(res => {<br />
console.log9(res) // 300<br />
})" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fn</span> (<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">await</span> <span class="hljs-number">100</span>
<span class="hljs-keyword">await</span> <span class="hljs-number">200</span>
<span class="hljs-keyword">return</span> <span class="hljs-number">300</span>
}
fn().then(<span class="hljs-function"><span class="hljs-params">res</span> =></span> {
<span class="hljs-built_in">console</span>.log9(res) <span class="hljs-comment">// 300</span>
})</code></pre>
<h3 id="articleHeader27">await</h3>
<p>await也是默认返回Promise对象,如果await后面不是一个Promise对象,就会转为立即resolve的Promise</p>
<p>如果一个await后面的Promise如果为reject,那么整个async都会中断执行,后面的awiat都不会执行,并且抛出错误,可以在async的<a href="http://www.js-code.com/tag/catch" title="catch" target="_blank">catch</a>中捕获错误</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="async function f() {
await Promise.reject('error');
await Promise.resolve('hello world'); // 不会执行
}
f().then(res =>{</p>
<p>}).catch(err=>{<br />
console.log(err) // error<br />
})" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">f</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.reject(<span class="hljs-string">'error'</span>);
<span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.resolve(<span class="hljs-string">'hello world'</span>); <span class="hljs-comment">// 不会执行</span>
}
f().then(<span class="hljs-function"><span class="hljs-params">res</span> =></span>{
}).catch(<span class="hljs-function"><span class="hljs-params">err</span>=></span>{
<span class="hljs-built_in">console</span>.log(err) <span class="hljs-comment">// error</span>
})</code></pre>
<p>如果希望一个await失败,后面的继续执行,可以使用<a href="http://www.js-code.com/tag/try" title="try" target="_blank">try</a>...<a href="http://www.js-code.com/tag/catch" title="catch" target="_blank">catch</a>或者在await后面的Promise跟一个catch方法:</p>
<div class="widget-codetool" style="display:none;">
<div class="widget-codetool--inner">
<span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br />
<span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="// try...catch
async function f() {
try {
await Promise.reject('出错了');
} catch(e) {
}
return await Promise.resolve('hello world');
}
f()
.then(v => console.log(v)) // hello world</p>
<p>// catch<br />
async function f() {<br />
await Promise.reject('出错了')<br />
.catch(e => console.log(e)); // 出错了<br />
return await Promise.resolve('hello world');<br />
}</p>
<p>f()<br />
.then(v => console.log(v)) // hello world" title="" data-original-title="复制"></span>
</div>
</p></div>
<pre class="javascript hljs"><code class="js"><span class="hljs-comment">// try...catch</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">f</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.reject(<span class="hljs-string">'出错了'</span>);
} <span class="hljs-keyword">catch</span>(e) {
}
<span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.resolve(<span class="hljs-string">'hello world'</span>);
}
f()
.then(<span class="hljs-function"><span class="hljs-params">v</span> =></span> <span class="hljs-built_in">console</span>.log(v)) <span class="hljs-comment">// hello world</span>
<span class="hljs-comment">// catch</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">f</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.reject(<span class="hljs-string">'出错了'</span>)
.catch(<span class="hljs-function"><span class="hljs-params">e</span> =></span> <span class="hljs-built_in">console</span>.log(e)); <span class="hljs-comment">// 出错了</span>
<span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.resolve(<span class="hljs-string">'hello world'</span>);
}
f()
.then(<span class="hljs-function"><span class="hljs-params">v</span> =></span> <span class="hljs-built_in">console</span>.log(v)) <span class="hljs-comment">// hello world</span></code></pre>
<p></code></p>