箭頭函數

箭頭函數表達式的語法比函數表達式更短,而且沒有本身的thisargumentssupernew.target。這些函數表達式更適用於那些本 來須要匿名函數的地方,而且它們不能用做構造函數。數組

首先:咱們先考慮一下這個箭頭函數沒有本身的thisargumentssuper>首先:咱們先考慮一下這個箭頭函數沒有本身的thisargumentssuper new.target`是什麼意思?帶着問題去看下面的內容會更事半功倍。app

1、語法

1.基礎語法
(參數1, 參數2, …, 參數N) => { 函數聲明 }

//至關於:(參數1, 參數2, …, 參數N) =>{ return 表達式; }
(參數1, 參數2, …, 參數N) => 表達式(單一)

// 當只有一個參數時,圓括號是可選的:
(單一參數) => {函數聲明}
單一參數 => {函數聲明}

// 沒有參數的函數應該寫成一對圓括號。
() => {函數聲明}
2.高級語法
//加括號的函數體返回對象字面表達式:
參數=> ({foo: bar})

//支持剩餘參數和默認參數
(參數1, 參數2, ...rest) => {函數聲明}
(參數1 = 默認值1,參數2, …, 參數N = 默認值N) => {函數聲明}

//一樣支持參數列表解構
let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f();  // 6

2、沒有本身的this,不綁定this

咱們先看一下下面的代碼,函數

const Person = {
    'name': 'little bear',
    'age': 18,
    'sayHello': function() {
        setTimeout(function() {
            console.log('我叫' + this.name + '我今年' + this.age + '歲!')
        }, 1000)
    }
}
console.log(Person.sayHello()) //我叫我今年undefined歲!

打印的結果是undefined,知道是什麼緣由嗎?固然,setTimeout方法裏面的this指向的是window,因此是undefined,sayhello方法中的this纔是指向Person的,若是按照下面的方式將sayHello中的this賦值給封閉變量self,就能夠正確打印結果了this

const Person1 = {
    'name': 'little bear',
    'age': 18,
    'sayHello': function() {
        var self = this;
        setTimeout(function() {
            console.log('我叫' + self.name + '我今年' + self.age + '歲!')
        }, 1000)
    }
}
console.log(Person1.sayHello());//我叫little bear我今年18歲!

咱們再看一下下面的代碼,想一想打印的結果是什麼呢?prototype

const Person3 = {
    'name': 'little bear',
    'age': 18,
    sayHello() {
        setTimeout(() => {
            console.log('我叫' + this.name + '我今年' + this.age + '歲!')
        }, 1000)
    }
}
console.log(Person3.sayHello());//我叫little bear我今年18歲!

這個結果是否如你所料呢?指針

箭頭函數不會建立本身的this,它只會從本身的做用域鏈的上一層繼承this。所以,在下面的代碼中,傳遞給setInterval的函數內的this與 封閉函數中的this值相同rest

咱們再看看下面的代碼就應該好理解了code

const Person5 = {
    'name': 'little bear',
    'age': 18,
    sayHello: () => {
        setTimeout(() => {
            console.log('我叫' + this.name + '我今年' + this.age + '歲!')
        }, 1000)
    }
}
Person5.sayHello();//我叫我今年undefined歲!

封閉函數的this指向的是外部對象windowsetTimeout繼承上一層this,因此也是指向的window對象

經過 call 或 apply 調用繼承

首先咱們回顧一下 callapply

  1. 他們各自的定義:

    • apply:調用一個對象的一個方法,用另外一個對象替換當前對象。例如:B.apply(A, arguments);即A對象應用B對象的方法。
    • call:調用一個對象的一個方法,用另外一個對象替換當前對象。例如:B.call(A, args1,args2);即A對象調用B對象的方法。
  2. 它們的共同之處:

    都「能夠用來代替另外一個對象調用一個方法,將一個函數的對象上下文從初始的上下文改變爲由thisObj指定的新對象」。

  3. 它們的不一樣之處:

    • apply:最多隻能有兩個參數——新this對象和一個數組argArray。若是給該方法傳遞多個參數,則把參數都寫進這個數組裏面,固然,即便只有一個參數,也要寫進數組裏。若是argArray不是一個有效的數組或arguments對象,那麼將致使一個TypeError。若是沒有提供argArray和thisObj任何一個參數,那麼Global對象將被用做thisObj,而且沒法被傳遞任何參數。
    • call:它能夠接受多個參數,第一個參數與apply同樣,後面則是一串參數列表。這個方法主要用在js對象各方法相互調用的時候,使當前this實例指針保持一致,或者在特殊狀況下須要改變this指針。若是沒有提供thisObj參數,那麼 Global 對象被用做thisObj。

咱們先來看一下下面的代碼,思考一下打印的結果,

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));         // 輸出 2
console.log(adder.addThruCall(1)); // 仍然輸出 2(而不是3 ——譯者注)

結果:

因爲 箭頭函數沒有本身的this指針,經過 call() 或 apply() 方法調用一個函數時,只能傳遞參數(不能綁定this---譯者注),他們的第一個參數會被忽略。(這種現象對於bind方法一樣成立---譯者注)

3、不綁定arguments

咱們都知道函數內部,argument是一個做爲函數輸入的值-原始數據或對象

var arguments = [5, 6, 7];

function person1(a, b, c) {
    console.log(arguments);
}
person1(1, 2);//arguments[1,2]

var arr1 = () => { return arguments; }
console.log(arr1());//[5,6,7]

var arr2 = (a) => { return arguments; }
console.log(arr2(1));//[5,6,7]

從上就能夠看出,通常的函數是綁定了Arguments 對象,而箭頭函數沒有綁定

看下面的代碼箭頭函數中的arguments只是引用了封閉做用域內的arguments

var arguments = [1, 2, 3];
var arr = () => arguments[0];

arr(); // 1

function foo(n) {
  var f = () => arguments[0] + n; // 隱式綁定 foo 函數的 arguments 對象. arguments[0] 是 n
  return f();
}

foo(1); // 2

4、使用 new 操做符

箭頭函數不能用做構造器,和 new一塊兒用會拋出錯誤。

var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor

5、使用prototype屬性

箭頭函數沒有prototype屬性。

var Foo = () => {};
console.log(Foo.prototype); // undefined

6、使用 yield 關鍵字

yield關鍵字一般不能在箭頭函數中使用(除非是嵌套在容許使用的函數內)。所以,箭頭函數不能用做生成器。

點擊能夠查看更多詳情

相關文章
相關標籤/搜索