//1. 前面圓括號,後面大括號 (param1, param2, …, paramN) => { statements; } /* 2.當刪除大括號時,它將是一個隱式的返回值,這意味着咱們不須要指定咱們返回*/ (param1, param2, …, paramN) => expression; // 等價於 (param1, param2, …, paramN) => { return expression; } // 3.若是隻有一個參數,圓括號是可選的: (singleParam) => { statements; } // 等價於 singleParam => { statements; } //4.若是箭頭函數 有多參數, 必須使用 ()圓括號: () => { statements; } //5.若是箭頭函數 無參數 , 必須使用 ()圓括號或者 _下劃線: () => { statements; } 或 _ => { statements; }
箭頭函數的引入有兩個方面的做用:一是更簡短的函數書寫,二是對 this
的詞法解析。javascript
更短的函數在函數式編程裏很受歡迎。試比較:java
var a = [ "Hydrogen", "Helium", "Lithium", "Beryllium" ]; var a2 = a.map(function(s){ return s.length }); var a3 = a.map( s => s.length );
var f = v => v; //上面的箭頭函數等同於: var f = function(v) { return v; };
在箭頭函數出現以前,每一個新定義的函數都有其本身的 this
值(例如,構造函數的 this 指向了一個新的對象;嚴格模式下的函數的 this
值爲 undefined
;若是函數是做爲對象的方法被調用的,則其 this 指向了那個調用它的對象)。在面向對象風格的編程中,這會帶來不少困擾。express
function Person() { // 構造函數 Person() 定義的 `this` 就是新實例對象本身 this.age = 0; setInterval(function growUp() { // 在非嚴格模式下,growUp() 函數定義了其內部的 `this`爲全局對象, // 不一樣於構造函數Person()的定義的 `this` this.age++; }, 3000); } var p = new Person();
在 ECMAScript 3/5 中,這個問題經過把this的值賦給變量,而後將該變量放到閉包中來解決。編程
function Person() { var self = this; // 也有人選擇使用 `that` 而非 `self`, 只要保證一致就好. self.age = 0; setInterval(function growUp() { // 回調裏面的 `self` 變量就指向了指望的那個對象了 self.age++; }, 3000); } var p = new Person();
除此以外,還可使用 bind 函數,把指望的 this
值傳遞給 growUp()
函數。segmentfault
this
值做爲本身的 this
值,所以下面的代碼將如期運行。閉包
function Person() { this.age = 0; setInterval(() => { // 回調裏面的 `this` 變量就指向了指望的那個對象了 this.age++; }, 3000); } var p = new Person();
1.如上所述,箭頭函數表達式對非方法函數是最合適的。讓咱們看看當咱們試着把它們做爲方法時發生了什麼。函數式編程
'use strict'; var obj = { i: 10, b: () => console.log(this.i, this), c: function() { console.log( this.i, this) } } obj.b(); // undefined obj.c(); // 10, Object {...}
箭頭函數沒有定義this綁定。 函數
2.另外一個涉及Object.defineProperty()
:的示例:ui
'use strict'; var obj = { a: 10 }; Object.defineProperty(obj, "b", { get: () => { console.log(this.a, typeof this.a, this); return this.a+10; // represents global object 'Window', therefore 'this.a' returns 'undefined' } });
函數體內的this
對象,就是定義時所在的對象,而不是使用時所在的對象。this
不能夠看成構造函數,也就是說,不可使用new
命令,不然會拋出一個錯誤。
不可使用arguments
對象,該對象在函數體內不存在。若是要用,能夠用Rest參數代替。
不可使用yield
命令,所以箭頭函數不能用做Generator
函數。
this
指向固定化ES5規範中,this
對象的指向是可變的,可是在ES6的箭頭函數中,它倒是固定的。
function foo() { setTimeout(() => { console.log('id:', this.id); }, 100); } var id = 21; foo.call({ id: 42 }); // 輸出 id: 42
注意:上面代碼中,
setTimeout
的參數是一個箭頭函數,這個箭頭函數的定義生效是在foo
函數生成時,而它的真正執行要等到100毫秒後。若是是普通函數,執行時this
應該指向全局對象window
,這時應該輸出21。可是,箭頭函數致使this老是指向函數定義生效時所在的對象(本例是{id: 42}
),因此輸出的是42。
箭頭函數不能用做構造器,和 new 一塊兒用就會拋出錯誤。
var Foo = () => {}; var foo = new Foo(); // TypeError: Foo is not a constructor
箭頭函數沒有原型屬性。
var Foo = () => {}; console.log(Foo.prototype); // undefined
請牢記,用 params => {object:literal}
這種簡單的語法返回一個文字表達式是行不通的:
var func = () => { foo: 1 }; // undefined! var func = () => { foo: function() {} }; // SyntaxError: function statement requires a name(未定義函數語句)
這是由於花括號(即 {}
)裏面的代碼被解析爲序列語句了(例如, foo
被認爲是一個標籤, 而非文字表達式的組成部分)。
因此,記得用圓括號把文字表達式包起來:
var func = () => ({ foo: 1 });