箭頭函數

一.語法

基礎語法

//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

1.更短的函數

更短的函數在函數式編程裏很受歡迎。試比較:java

var a = [
  "Hydrogen",
  "Helium",
  "Lithium",
  "Beryl­lium"
];

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;
};

2.不綁定this

在箭頭函數出現以前,每一個新定義的函數都有其本身的 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

3.箭頭函數會捕獲其所在上下文的  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'
  }
});

3.箭頭函數使用注意點 http://www.javashuo.com/article/p-gmfwqrpy-h.html

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

  2. 不能夠看成構造函數,也就是說,不可使用new命令,不然會拋出一個錯誤。

  3. 不可使用arguments對象,該對象在函數體內不存在。若是要用,能夠用Rest參數代替。

  4. 不可使用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操做符

箭頭函數不能用做構造器,和 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 });
相關文章
相關標籤/搜索