JavaScript箭頭函數(Arrow Function)

ES6標準新增了一種新的函數:Arrow Function(箭頭函數)html

更簡潔的語法

咱們先來按常規語法定義函數:express

function (x) {
    return x * x;
}

該函數使用箭頭函數可使用僅僅一行代碼搞定!app

x => x * x

箭頭函數至關於匿名函數,而且簡化了函數定義。函數

箭頭函數有兩種格式:學習

  • 一種像上面的,只包含一個表達式,連{ ... }return都省略掉了。
  • 還有一種能夠包含多條語句,這時候就不能省略{ ... }return。
x => {
    if (x > 0) {
        return x * x;
    }
    else {
        return - x * x;
    }
}

咱們能夠看一下箭頭函數的語法規則:this

(parameters) => { statements }

本文上面的例子中,函數有一個參數。若是函數有多個參數或者沒有參數,可按照下面寫法:spa

若是返回值僅僅只有一個表達式(expression), 還能夠省略大括號。rest

// 無參數:
() => 3.14

//一個參數
//若是隻有一個參數,能夠省略括號:
x=>x*x

// 兩個參數:
(x, y) => x * x + y * y

// 可變參數:
(x, y, ...rest) => {
    var i, sum = x + y;
    for (i=0; i<rest.length; i++) {
        sum += rest[i];
    }
    return sum;
}

注意:若是要返回一個對象,就要注意,若是是單表達式,這麼寫的話會報錯:code

// SyntaxError:
x => { foo: x }

由於和函數體的 { ... } 有語法衝突,因此要改成:htm

// ok:
x => ({ foo: x })

沒有局部this的綁定

箭頭函數看上去是匿名函數的一種簡寫,但實際上,箭頭函數和匿名函數有個明顯的區別:箭頭函數內部的this是詞法做用域,由上下文肯定。箭頭函數不會綁定this。 或則說箭頭函數不會改變this原本的綁定。

舉個例子說明:

function Counter() {
  this.num = 0;
}
var a = new Counter();

 console.log(a.num);// 0

由於使用了關鍵字 new 構造,Count()函數中的 this 綁定到一個新的對象,而且賦值給a。經過 console.log 打印 a.num,會輸出0。

若是咱們想每過一秒將 a.num 的值加1,該如何實現呢?可使用 setInterval() 函數。

function Counter() {
  this.num = 0;
  this.timer = setInterval(function add() {
    this.num++;
    console.log(this.num);
  }, 1000);
}

var b = new Counter();
// NaN
// NaN
// NaN
// ...

每隔一秒都會有一個NaN打印出來,而不是累加的數字。

緣由:首先函數 setInterval 沒有被某個聲明的對象調用,也沒有使用 new 關鍵字,再之沒有使用 bind ,  call 和 apply 。 setInterval 只是一個普通的函數。實際上 setInterval 裏面的 this 綁定到全局對象的。

之因此打印 NaN ,是由於 this.num 綁定到 window 對象的 num ,而 window.num 未定義。

解決辦法:使用箭頭函數!使用箭頭函數就不會致使 this 被綁定到全局對象。

function Counter() {
  this.num = 0;
  this.timer = setInterval(() => {
    this.num++;
    console.log(this.num);
  }, 1000);
}
var b = new Counter();
// 1
// 2
// 3
// ...

經過 Counter 構造函數綁定的 this 將會被保留。在 setInterval 函數中, this 依然指向咱們新建立的b對象。

再舉個例子:

因爲JavaScript函數對 this 綁定的錯誤處理,下面的例子沒法獲得預期結果:

var obj = {
    birth: 1990,
    getAge: function () {
        var b = this.birth; // 1990
        var fn = function () {
            return new Date().getFullYear() - this.birth; // this指向window或undefined
        };
        return fn();
    }
};

如今,箭頭函數徹底修復了 this 的指向, this 老是指向詞法做用域,也就是外層調用者 obj :

var obj = {
    birth: 1990,
    getAge: function () {
        var b = this.birth; // 1990
        var fn = () => new Date().getFullYear() - this.birth; // this指向obj對象
        return fn();
    }
};
obj.getAge(); // 25

若是使用箭頭函數,之前的那種hack寫法:

var that = this;

就再也不須要了。

因爲this在箭頭函數中已經按照詞法做用域綁定了,因此,用 call() 或者 apply() 調用箭頭函數時,沒法對 this 進行綁定,即傳入的第一個參數被忽略:

var obj = {
    birth: 1990,
    getAge: function (year) {
        var b = this.birth; // 1990
        var fn = (y) => y - this.birth; // this.birth還是1990
        return fn.call({birth:2000}, year);
    }
};
obj.getAge(2015); // 25

 

本文部份內容借鑑自:JavaScript學習筆記(十二)——箭頭函數(Arrow Function)

 

親,若是您感受本文有用,請點個贊再走吧✌(>‿◠)!!

相關文章
相關標籤/搜索