ES6 箭頭函數 從瞭解到深刻

箭頭函數

1. 簡單的定義:

胖箭頭函數 Fat arrow functions,又稱箭頭函數,是一個來自ECMAScript 2015(又稱ES6)的全
新特性。有傳聞說,箭頭函數的語法=>,是受到了CoffeeScript 的影響,而且它與CoffeeScript中的
=>語法同樣,共享this上下文。javascript

箭頭函數的產生,主要由兩個目的:更簡潔的語法和與父做用域共享關鍵字this。接下來,讓咱們來看幾個詳細的例子
當須要編寫一個簡單的單一參數函數時,能夠採用箭頭函數來書寫,標識名 => 表達式。
這樣就能夠省卻 functionreturn 的輸入,還有括號,分號等。箭頭函數是ES6
增長的一個特性。java

let f = v => v;

最直接的感受就是簡便,固然不可能就是這麼一點好處,下面就一塊兒來探討一下。app

幾個小細節 :

  • 若是箭頭函數的代碼塊多餘一條語句,就必需要使用大括號將其括起來,而且使用
    return 語句返回。函數

  • 因爲大括號會被解釋位爲代碼塊,因此若是箭頭函數直接返回一個對象,必須在外
    面加上括號。this

let f = id => ({age: 22, name: Alice })
  • 箭頭函數還能夠和解構賦值 Destructuring 聯合使用.rest

const f = ({first, last}) => first + '' + last;
  • 能夠簡化回調函數,大大簡化和縮短代碼行數。code

2. 箭頭函數和普通函數的區別

  • this的指向
    普通函數與箭頭函數有個微小的不一樣點。 箭頭函數沒有本身的this值 ,其this值是通對象

過繼承其它傳入對象而得到的,一般來講是上一級外部函數的 this 的指向。繼承

function f() {
    setTimeout( () => {
      console.log("id:", this.id);
    },100);
  }

  f.call( { id: 42 }); //id: 42;

這個例子中, setTimeout 的參數是一個箭頭函數, 每隔100毫秒運行一次,若是是普通函
數,執行的 this 應該指向全局對象, 可是箭頭函數會讓 this 老是指向函數所在的對象ip

箭頭函數裏面嵌套箭頭函數會有多少個this呢?
看一個簡單的例子

function f() {
    return () => {
      return () => {
        return () => {
          console.log("id:", this.id);
        };
      };
    };
  }
  f().call( {id: 42})()()(); //id: 42

上面的代碼中只有一個 this, 就是函數f的this 。這是由於全部的內層函數都是箭頭函數
都沒有本身的this,都是最外層f函數的this。
注意:還有三個變量在箭頭函數中也是不存在的arguments , super, new.target因此順理成
章,箭頭函數也就不能再用這些方法call(),apply(),bind(),由於這是一些改變this指向的方法,
箭頭函數並無this啊。

var adder = {
    base : 1,
    add : function(a) {
    var f = v => v + this.base; return f(a);
  },
    addThruCall: function(a) {
    var f = v => v + this.base;
    var b = { base : 2 };
    return f.call(b, a);
  }
};
    console.log(adder.add(1));

3. 怎麼處理好箭頭函數的使用問題呢?

  • 使用非箭頭函數來處理由object.method()語法調用的方法。由於它們會接收到來自調用者的
    有意義的this值。

  • 在其它場合都使用箭頭函數。

4. 使用箭頭函數的注意點

  • 箭頭函數在參數和箭頭之間不能換行。

  • 函數體內的this對象就是定義時所在的對象,而不是使用時所在的對象。

'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'
  }
});
  • 不能夠看成構造函數,簡單說就是不能再使用new命令了,否則會報錯。

var Foo = () => {};
var foo = new Foo();
// TypeError: Foo is not a constructor
  • 不可使用arguments 對象,該對象在函數體內不存在,若是實在要用能夠用rest代替。

  • 不可使用yield命令,箭頭函數不可用做Generator函數。

值得注意的一點就是this對象的指向是可變的,但在箭頭函數內是固定的。

5. 總結

箭頭函數是我最喜歡的ES6特性之一。使用=>來代替function是很是便捷的。但我也曾見過只使用
=>來聲明函數的代碼,我並不認爲這是好的作法,由於=>也提供了它區別於傳統function,其所
獨有的特性。我我的推薦,僅在你須要使用它提供的新特性時,才使用它。

  • 當只有一條聲明語句(statement)時, 隱式 return

  • 須要使用到父做用域中的this

相關文章
相關標籤/搜索