转载自:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions
箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或 new.target。这些函数表达式更适用于那些本来需要匿名函数的地方,并且它们不能用作构造函数。
参考 "ES6 In Depth: Arrow functions" on hacks.mozilla.org.
引入箭头函数有两个方面的作用:更简短的函数并且不绑定this。
在箭头函数出现之前,每个新定义的函数都有它自己的 this值(在构造函数的情况下是一个新对象,在严格模式的函数调用中为 undefined,如果该函数被作为“对象方法”调用则为基础对象等)。This被证明是令人厌烦的面向对象风格的编程。
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">function</span> <span style="color:#dd4a68">Person</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span> <span style="color:#708090">// Person() 构造函数定义 `this`作为它自己的实例.</span> <span style="color:#0077aa">this</span><span style="color:#999999">.</span>age <span style="color:#9a6e3a">=</span> <span style="color:#990055">0</span><span style="color:#999999">;</span> <span style="color:#dd4a68">setInterval</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span> <span style="color:#dd4a68">growUp</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span> <span style="color:#708090">// 在非严格模式, growUp()函数定义 `this`作为全局对象, </span> <span style="color:#708090">// 与在 Person()构造函数中定义的 `this`并不相同.</span> <span style="color:#0077aa">this</span><span style="color:#999999">.</span>age<span style="color:#9a6e3a">++</span><span style="color:#999999">;</span> <span style="color:#999999">}</span><span style="color:#999999">,</span> <span style="color:#990055">1000</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#999999">}</span> <span style="color:#0077aa">var</span> p <span style="color:#9a6e3a">=</span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Person</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>在ECMAScript 3/5中,通过将this值分配给封闭的变量,可以解决this问题。
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">function</span> <span style="color:#dd4a68">Person</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span> <span style="color:#0077aa">var</span> that <span style="color:#9a6e3a">=</span> <span style="color:#0077aa">this</span><span style="color:#999999">;</span> that<span style="color:#999999">.</span>age <span style="color:#9a6e3a">=</span> <span style="color:#990055">0</span><span style="color:#999999">;</span> <span style="color:#dd4a68">setInterval</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span> <span style="color:#dd4a68">growUp</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span> <span style="color:#708090">// 回调引用的是`that`变量, 其值是预期的对象. </span> that<span style="color:#999999">.</span>age<span style="color:#9a6e3a">++</span><span style="color:#999999">;</span> <span style="color:#999999">}</span><span style="color:#999999">,</span> <span style="color:#990055">1000</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#999999">}</span></code></span>或者,可以创建绑定函数,以便将预先分配的this值传递到绑定的目标函数(上述示例中的growUp()函数)。
箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this。因此,在下面的代码中,传递给setInterval的函数内的this与封闭函数中的this值相同:
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">function</span> <span style="color:#dd4a68">Person</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span> <span style="color:#0077aa">this</span><span style="color:#999999">.</span>age <span style="color:#9a6e3a">=</span> <span style="color:#990055">0</span><span style="color:#999999">;</span> <span style="color:#dd4a68">setInterval</span><span style="color:#999999">(</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> <span style="color:#999999">{</span> <span style="color:#0077aa">this</span><span style="color:#999999">.</span>age<span style="color:#9a6e3a">++</span><span style="color:#999999">;</span> <span style="color:#708090">// |this| 正确地指向 p 实例</span> <span style="color:#999999">}</span><span style="color:#999999">,</span> <span style="color:#990055">1000</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#999999">}</span> <span style="color:#0077aa">var</span> p <span style="color:#9a6e3a">=</span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Person</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>与严格模式的关系
鉴于 this 是词法层面上的,严格模式中与 this 相关的规则都将被忽略。
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">function</span> <span style="color:#dd4a68">Person</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span> <span style="color:#0077aa">this</span><span style="color:#999999">.</span>age <span style="color:#9a6e3a">=</span> <span style="color:#990055">0</span><span style="color:#999999">;</span> <span style="color:#0077aa">var</span> closure <span style="color:#9a6e3a">=</span> <span style="color:#669900">"123"</span> <span style="color:#dd4a68">setInterval</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span> <span style="color:#dd4a68">growUp</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span> <span style="color:#0077aa">this</span><span style="color:#999999">.</span>age<span style="color:#9a6e3a">++</span><span style="color:#999999">;</span> console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>closure<span style="color:#999999">)</span> <span style="color:#999999">}</span><span style="color:#999999">,</span> <span style="color:#990055">1000</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#999999">}</span> <span style="color:#0077aa">var</span> p <span style="color:#9a6e3a">=</span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Person</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#0077aa">function</span> <span style="color:#dd4a68">PersonX</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span> <span style="color:#669900">'use strict'</span> <span style="color:#0077aa">this</span><span style="color:#999999">.</span>age <span style="color:#9a6e3a">=</span> <span style="color:#990055">0</span><span style="color:#999999">;</span> <span style="color:#0077aa">var</span> closure <span style="color:#9a6e3a">=</span> <span style="color:#669900">"123"</span> <span style="color:#dd4a68">setInterval</span><span style="color:#999999">(</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#9a6e3a">=></span><span style="color:#999999">{</span> <span style="color:#0077aa">this</span><span style="color:#999999">.</span>age<span style="color:#9a6e3a">++</span><span style="color:#999999">;</span> console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>closure<span style="color:#999999">)</span> <span style="color:#999999">}</span><span style="color:#999999">,</span> <span style="color:#990055">1000</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#999999">}</span> <span style="color:#0077aa">var</span> px <span style="color:#9a6e3a">=</span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">PersonX</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>严格模式的其他规则依然不变.
通过 call 或 apply 调用
由于 箭头函数没有自己的this指针,通过 call() 或 apply() 方法调用一个函数时,只能传递参数(不能绑定this---译者注),他们的第一个参数会被忽略。(这种现象对于bind方法同样成立---译者注)
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">var</span> adder <span style="color:#9a6e3a">=</span> <span style="color:#999999">{</span> base <span style="color:#999999">:</span> <span style="color:#990055">1</span><span style="color:#999999">,</span> <span style="color:#dd4a68">add</span> <span style="color:#999999">:</span> <span style="color:#0077aa">function</span><span style="color:#999999">(</span>a<span style="color:#999999">)</span> <span style="color:#999999">{</span> <span style="color:#0077aa">var</span> <span style="color:#dd4a68">f</span> <span style="color:#9a6e3a">=</span> v <span style="color:#9a6e3a">=></span> v <span style="color:#9a6e3a">+</span> <span style="color:#0077aa">this</span><span style="color:#999999">.</span>base<span style="color:#999999">;</span> <span style="color:#0077aa">return</span> <span style="color:#dd4a68">f</span><span style="color:#999999">(</span>a<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#999999">}</span><span style="color:#999999">,</span> <span style="color:#dd4a68">addThruCall</span><span style="color:#999999">:</span> <span style="color:#0077aa">function</span><span style="color:#999999">(</span>a<span style="color:#999999">)</span> <span style="color:#999999">{</span> <span style="color:#0077aa">var</span> <span style="color:#dd4a68">f</span> <span style="color:#9a6e3a">=</span> v <span style="color:#9a6e3a">=></span> v <span style="color:#9a6e3a">+</span> <span style="color:#0077aa">this</span><span style="color:#999999">.</span>base<span style="color:#999999">;</span> <span style="color:#0077aa">var</span> b <span style="color:#9a6e3a">=</span> <span style="color:#999999">{</span> base <span style="color:#999999">:</span> <span style="color:#990055">2</span> <span style="color:#999999">}</span><span style="color:#999999">;</span> <span style="color:#0077aa">return</span> <span style="color:#dd4a68">f</span><span style="color:#999999">.</span><span style="color:#dd4a68">call</span><span style="color:#999999">(</span>b<span style="color:#999999">,</span> a<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#999999">}</span> <span style="color:#999999">}</span><span style="color:#999999">;</span> console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>adder<span style="color:#999999">.</span><span style="color:#dd4a68">add</span><span style="color:#999999">(</span><span style="color:#990055">1</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 输出 2</span> console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>adder<span style="color:#999999">.</span><span style="color:#dd4a68">addThruCall</span><span style="color:#999999">(</span><span style="color:#990055">1</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 仍然输出 2(而不是3 ——译者注)</span></code></span>箭头函数不绑定Arguments 对象。因此,在本示例中,arguments只是引用了封闭作用域内的arguments:
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">var</span> arguments <span style="color:#9a6e3a">=</span> <span style="color:#999999">[</span><span style="color:#990055">1</span><span style="color:#999999">,</span> <span style="color:#990055">2</span><span style="color:#999999">,</span> <span style="color:#990055">3</span><span style="color:#999999">]</span><span style="color:#999999">;</span> <span style="color:#0077aa">var</span> <span style="color:#dd4a68">arr</span> <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> arguments<span style="color:#999999">[</span><span style="color:#990055">0</span><span style="color:#999999">]</span><span style="color:#999999">;</span> <span style="color:#dd4a68">arr</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 1</span> <span style="color:#0077aa">function</span> <span style="color:#dd4a68">foo</span><span style="color:#999999">(</span>n<span style="color:#999999">)</span> <span style="color:#999999">{</span> <span style="color:#0077aa">var</span> <span style="color:#dd4a68">f</span> <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> arguments<span style="color:#999999">[</span><span style="color:#990055">0</span><span style="color:#999999">]</span> <span style="color:#9a6e3a">+</span> n<span style="color:#999999">;</span> <span style="color:#708090">// 隐式绑定 foo 函数的 arguments 对象. arguments[0] 是 n</span> <span style="color:#0077aa">return</span> <span style="color:#dd4a68">f</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#999999">}</span> <span style="color:#dd4a68">foo</span><span style="color:#999999">(</span><span style="color:#990055">1</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 2</span></code></span>在大多数情况下,使用剩余参数是相较使用arguments对象的更好选择。
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">function</span> <span style="color:#dd4a68">foo</span><span style="color:#999999">(</span>arg<span style="color:#999999">)</span> <span style="color:#999999">{</span> <span style="color:#0077aa">var</span> <span style="color:#dd4a68">f</span> <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span><span style="color:#9a6e3a">...</span>args<span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> args<span style="color:#999999">[</span><span style="color:#990055">0</span><span style="color:#999999">]</span><span style="color:#999999">;</span> <span style="color:#0077aa">return</span> <span style="color:#dd4a68">f</span><span style="color:#999999">(</span>arg<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#999999">}</span> <span style="color:#dd4a68">foo</span><span style="color:#999999">(</span><span style="color:#990055">1</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 1</span> <span style="color:#0077aa">function</span> <span style="color:#dd4a68">foo</span><span style="color:#999999">(</span>arg1<span style="color:#999999">,</span>arg2<span style="color:#999999">)</span> <span style="color:#999999">{</span> <span style="color:#0077aa">var</span> <span style="color:#dd4a68">f</span> <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span><span style="color:#9a6e3a">...</span>args<span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> args<span style="color:#999999">[</span><span style="color:#990055">1</span><span style="color:#999999">]</span><span style="color:#999999">;</span> <span style="color:#0077aa">return</span> <span style="color:#dd4a68">f</span><span style="color:#999999">(</span>arg1<span style="color:#999999">,</span>arg2<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#999999">}</span> <span style="color:#dd4a68">foo</span><span style="color:#999999">(</span><span style="color:#990055">1</span><span style="color:#999999">,</span><span style="color:#990055">2</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">//2</span></code></span>如上所述,箭头函数表达式对非方法函数是最合适的。让我们看看当我们试着把它们作为方法时发生了什么。
<span style="color:#333333"><code class="language-js"><span style="color:#669900">'use strict'</span><span style="color:#999999">;</span> <span style="color:#0077aa">var</span> obj <span style="color:#9a6e3a">=</span> <span style="color:#999999">{</span> i<span style="color:#999999">:</span> <span style="color:#990055">10</span><span style="color:#999999">,</span> <span style="color:#dd4a68">b</span><span style="color:#999999">:</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#0077aa">this</span><span style="color:#999999">.</span>i<span style="color:#999999">,</span> <span style="color:#0077aa">this</span><span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#dd4a68">c</span><span style="color:#999999">:</span> <span style="color:#0077aa">function</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span> console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span> <span style="color:#0077aa">this</span><span style="color:#999999">.</span>i<span style="color:#999999">,</span> <span style="color:#0077aa">this</span><span style="color:#999999">)</span> <span style="color:#999999">}</span> <span style="color:#999999">}</span> obj<span style="color:#999999">.</span><span style="color:#dd4a68">b</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// undefined, Window{...}</span> obj<span style="color:#999999">.</span><span style="color:#dd4a68">c</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 10, Object {...}</span></code></span>箭头函数没有定义this绑定。另一个涉及Object.defineProperty()的示例:
<span style="color:#333333"><code class="language-js"><span style="color:#669900">'use strict'</span><span style="color:#999999">;</span> <span style="color:#0077aa">var</span> obj <span style="color:#9a6e3a">=</span> <span style="color:#999999">{</span> a<span style="color:#999999">:</span> <span style="color:#990055">10</span> <span style="color:#999999">}</span><span style="color:#999999">;</span> Object<span style="color:#999999">.</span><span style="color:#dd4a68">defineProperty</span><span style="color:#999999">(</span>obj<span style="color:#999999">,</span> <span style="color:#669900">"b"</span><span style="color:#999999">,</span> <span style="color:#999999">{</span> <span style="color:#dd4a68">get</span><span style="color:#999999">:</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> <span style="color:#999999">{</span> console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#0077aa">this</span><span style="color:#999999">.</span>a<span style="color:#999999">,</span> <span style="color:#0077aa">typeof</span> <span style="color:#0077aa">this</span><span style="color:#999999">.</span>a<span style="color:#999999">,</span> <span style="color:#0077aa">this</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#0077aa">return</span> <span style="color:#0077aa">this</span><span style="color:#999999">.</span>a<span style="color:#9a6e3a">+</span><span style="color:#990055">10</span><span style="color:#999999">;</span> <span style="color:#708090">// 代表全局对象 'Window', 因此 'this.a' 返回 'undefined'</span> <span style="color:#999999">}</span> <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span> obj<span style="color:#999999">.</span>b<span style="color:#999999">;</span> <span style="color:#708090">// undefined "undefined" Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}</span></code></span>箭头函数不能用作构造器,和 new一起用会抛出错误。
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">var</span> <span style="color:#dd4a68">Foo</span> <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> <span style="color:#999999">{</span><span style="color:#999999">}</span><span style="color:#999999">;</span> <span style="color:#0077aa">var</span> foo <span style="color:#9a6e3a">=</span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Foo</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// TypeError: Foo is not a constructor</span></code></span>箭头函数没有prototype属性。
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">var</span> <span style="color:#dd4a68">Foo</span> <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> <span style="color:#999999">{</span><span style="color:#999999">}</span><span style="color:#999999">;</span> console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#dd4a68">Foo</span><span style="color:#999999">.</span>prototype<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// undefined</span></code></span>yield 关键字通常不能在箭头函数中使用(除非是嵌套在允许使用的函数内)。因此,箭头函数不能用作生成器。
箭头函数可以有一个“简写体”或常见的“块体”。
在一个简写体中,只需要一个表达式,并附加一个隐式的返回值。在块体中,必须使用明确的return语句。
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">var</span> <span style="color:#dd4a68">func</span> <span style="color:#9a6e3a">=</span> x <span style="color:#9a6e3a">=></span> x <span style="color:#9a6e3a">*</span> x<span style="color:#999999">;</span> <span style="color:#708090">// 简写函数 省略return</span> <span style="color:#0077aa">var</span> <span style="color:#dd4a68">func</span> <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span>x<span style="color:#999999">,</span> y<span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> <span style="color:#999999">{</span> <span style="color:#0077aa">return</span> x <span style="color:#9a6e3a">+</span> y<span style="color:#999999">;</span> <span style="color:#999999">}</span><span style="color:#999999">;</span> <span style="color:#708090">//常规编写 明确的返回值</span></code></span>记住用params => {object:literal}这种简单的语法返回对象字面量是行不通的。
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">var</span> <span style="color:#dd4a68">func</span> <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> <span style="color:#999999">{</span> foo<span style="color:#999999">:</span> <span style="color:#990055">1</span> <span style="color:#999999">}</span><span style="color:#999999">;</span> <span style="color:#708090">// Calling func() returns undefined!</span> <span style="color:#0077aa">var</span> <span style="color:#dd4a68">func</span> <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> <span style="color:#999999">{</span> <span style="color:#dd4a68">foo</span><span style="color:#999999">:</span> <span style="color:#0077aa">function</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span><span style="color:#999999">}</span> <span style="color:#999999">}</span><span style="color:#999999">;</span> <span style="color:#708090">// SyntaxError: function statement requires a name</span></code></span>这是因为花括号({} )里面的代码被解析为一系列语句(即 foo 被认为是一个标签,而非对象字面量的组成部分)。
所以,记得用圆括号把对象字面量包起来:
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">var</span> <span style="color:#dd4a68">func</span> <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> <span style="color:#999999">(</span><span style="color:#999999">{</span>foo<span style="color:#999999">:</span> <span style="color:#990055">1</span><span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>箭头函数在参数和箭头之间不能换行。
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">var</span> <span style="color:#dd4a68">func</span> <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> <span style="color:#990055">1</span><span style="color:#999999">;</span> <span style="color:#708090">// SyntaxError: expected expression, got '=>'</span></code></span>虽然箭头函数中的箭头不是运算符,但箭头函数具有与常规函数不同的特殊运算符优先级解析规则。
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">let</span> callback<span style="color:#999999">;</span> callback <span style="color:#9a6e3a">=</span> callback <span style="color:#9a6e3a">||</span> <span style="color:#0077aa">function</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span><span style="color:#999999">}</span><span style="color:#999999">;</span> <span style="color:#708090">// ok</span> callback <span style="color:#9a6e3a">=</span> callback <span style="color:#9a6e3a">||</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> <span style="color:#999999">{</span><span style="color:#999999">}</span><span style="color:#999999">;</span> <span style="color:#708090">// SyntaxError: invalid arrow-function arguments</span> callback <span style="color:#9a6e3a">=</span> callback <span style="color:#9a6e3a">||</span> <span style="color:#999999">(</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> <span style="color:#999999">{</span><span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// ok</span></code></span>
箭头函数也可以使用条件(三元)运算符:
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">var</span> <span style="color:#dd4a68">simple</span> <span style="color:#9a6e3a">=</span> a <span style="color:#9a6e3a">=></span> a <span style="color:#9a6e3a">></span> <span style="color:#990055">15</span> <span style="color:#9a6e3a">?</span> <span style="color:#990055">15</span> <span style="color:#999999">:</span> a<span style="color:#999999">;</span> <span style="color:#dd4a68">simple</span><span style="color:#999999">(</span><span style="color:#990055">16</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 15</span> <span style="color:#dd4a68">simple</span><span style="color:#999999">(</span><span style="color:#990055">10</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 10</span> <span style="color:#0077aa">let</span> <span style="color:#dd4a68">max</span> <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span>a<span style="color:#999999">,</span> b<span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> a <span style="color:#9a6e3a">></span> b <span style="color:#9a6e3a">?</span> a <span style="color:#999999">:</span> b<span style="color:#999999">;</span></code></span>
箭头函数内定义的变量及其作用域
<span style="color:#333333"><code class="language-js"><span style="color:#708090">// 常规写法</span> <span style="color:#0077aa">var</span> <span style="color:#dd4a68">greeting</span> <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> <span style="color:#999999">{</span><span style="color:#0077aa">let</span> now <span style="color:#9a6e3a">=</span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Date</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#0077aa">return</span> <span style="color:#999999">(</span><span style="color:#669900">"Good"</span> <span style="color:#9a6e3a">+</span> <span style="color:#999999">(</span><span style="color:#999999">(</span>now<span style="color:#999999">.</span><span style="color:#dd4a68">getHours</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">></span> <span style="color:#990055">17</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">?</span> <span style="color:#669900">" evening."</span> <span style="color:#999999">:</span> <span style="color:#669900">" day."</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span> <span style="color:#dd4a68">greeting</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">//"Good day."</span> console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>now<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// ReferenceError: now is not defined 标准的let作用域</span> <span style="color:#708090">// 参数括号内定义的变量是局部变量(默认参数)</span> <span style="color:#0077aa">var</span> greeting <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span>now<span style="color:#9a6e3a">=</span><span style="color:#0077aa">new</span> <span style="color:#dd4a68">Date</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> <span style="color:#669900">"Good"</span> <span style="color:#9a6e3a">+</span> <span style="color:#999999">(</span>now<span style="color:#999999">.</span><span style="color:#dd4a68">getHours</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">></span> <span style="color:#990055">17</span> <span style="color:#9a6e3a">?</span> <span style="color:#669900">" evening."</span> <span style="color:#999999">:</span> <span style="color:#669900">" day."</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#dd4a68">greeting</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">//"Good day."</span> console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>now<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// ReferenceError: now is not defined</span> <span style="color:#708090">// 对比:函数体内{}不使用var定义的变量是全局变量</span> <span style="color:#0077aa">var</span> <span style="color:#dd4a68">greeting</span> <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> <span style="color:#999999">{</span>now <span style="color:#9a6e3a">=</span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Date</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#0077aa">return</span> <span style="color:#999999">(</span><span style="color:#669900">"Good"</span> <span style="color:#9a6e3a">+</span> <span style="color:#999999">(</span><span style="color:#999999">(</span>now<span style="color:#999999">.</span><span style="color:#dd4a68">getHours</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">></span> <span style="color:#990055">17</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">?</span> <span style="color:#669900">" evening."</span> <span style="color:#999999">:</span> <span style="color:#669900">" day."</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span> <span style="color:#dd4a68">greeting</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">//"Good day."</span> console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>now<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// Fri Dec 22 2017 10:01:00 GMT+0800 (中国标准时间)</span> <span style="color:#708090">// 对比:函数体内{} 用var定义的变量是局部变量</span> <span style="color:#0077aa">var</span> <span style="color:#dd4a68">greeting</span> <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> <span style="color:#999999">{</span><span style="color:#0077aa">var</span> now <span style="color:#9a6e3a">=</span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Date</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#0077aa">return</span> <span style="color:#999999">(</span><span style="color:#669900">"Good"</span> <span style="color:#9a6e3a">+</span> <span style="color:#999999">(</span><span style="color:#999999">(</span>now<span style="color:#999999">.</span><span style="color:#dd4a68">getHours</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">></span> <span style="color:#990055">17</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">?</span> <span style="color:#669900">" evening."</span> <span style="color:#999999">:</span> <span style="color:#669900">" day."</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span> <span style="color:#dd4a68">greeting</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">//"Good day."</span> console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>now<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// ReferenceError: now is not defined</span></code></span>
箭头函数也可以使用闭包:
<span style="color:#333333"><code class="language-js"><span style="color:#708090">// 标准的闭包函数</span> <span style="color:#0077aa">function</span> <span style="color:#990055">A</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span> <span style="color:#0077aa">var</span> i<span style="color:#9a6e3a">=</span><span style="color:#990055">0</span><span style="color:#999999">;</span> <span style="color:#0077aa">return</span> <span style="color:#0077aa">function</span> <span style="color:#dd4a68">b</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span> <span style="color:#0077aa">return</span> <span style="color:#999999">(</span><span style="color:#9a6e3a">++</span>i<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#999999">}</span><span style="color:#999999">;</span> <span style="color:#999999">}</span><span style="color:#999999">;</span> <span style="color:#0077aa">var</span> v<span style="color:#9a6e3a">=</span><span style="color:#990055">A</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#dd4a68">v</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">//1</span> <span style="color:#dd4a68">v</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">//2</span> <span style="color:#708090">//箭头函数体的闭包( i=0 是默认参数)</span> <span style="color:#0077aa">var</span> <span style="color:#dd4a68">Add</span> <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span>i<span style="color:#9a6e3a">=</span><span style="color:#990055">0</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> <span style="color:#999999">{</span><span style="color:#0077aa">return</span> <span style="color:#999999">(</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> <span style="color:#999999">(</span><span style="color:#9a6e3a">++</span>i<span style="color:#999999">)</span> <span style="color:#999999">)</span><span style="color:#999999">}</span><span style="color:#999999">;</span> <span style="color:#0077aa">var</span> v <span style="color:#9a6e3a">=</span> <span style="color:#dd4a68">Add</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#dd4a68">v</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">//1</span> <span style="color:#dd4a68">v</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">//2</span> <span style="color:#708090">//因为仅有一个返回,return 及括号()也可以省略</span> <span style="color:#0077aa">var</span> <span style="color:#dd4a68">Add</span> <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span>i<span style="color:#9a6e3a">=</span><span style="color:#990055">0</span><span style="color:#999999">)</span><span style="color:#9a6e3a">=></span> <span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#9a6e3a">=></span> <span style="color:#999999">(</span><span style="color:#9a6e3a">++</span>i<span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>
箭头函数递归
<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">var</span> <span style="color:#dd4a68">fact</span> <span style="color:#9a6e3a">=</span> <span style="color:#999999">(</span>x<span style="color:#999999">)</span> <span style="color:#9a6e3a">=></span> <span style="color:#999999">(</span> x<span style="color:#9a6e3a">==</span><span style="color:#990055">0</span> <span style="color:#9a6e3a">?</span> <span style="color:#990055">1</span> <span style="color:#999999">:</span> x<span style="color:#9a6e3a">*</span><span style="color:#dd4a68">fact</span><span style="color:#999999">(</span>x<span style="color:#9a6e3a">-</span><span style="color:#990055">1</span><span style="color:#999999">)</span> <span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#dd4a68">fact</span><span style="color:#999999">(</span><span style="color:#990055">5</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 120</span></code></span>