ES6—箭頭函數

  ES6中,可使用箭頭(=>)函數表達式的語法定義函數,這種函數表達式更適用於那些原本須要匿名函數的地方,注意它們不能用做構造函數。javascript

基本用法

//參數、返回值單一
var f=x=>x;
//多個參數
var f=(x,y)=>x+y;
//函數體有多條語句
var f=(x,y)=>{var re=x+y;return re;};
//返回對象必須有:小括號()
var f=()=>({name:xuux,age:24});

//使用條件運算符
let max = (a, b) => a > b ? a : b;

//閉包( i=0 是默認參數)
var Add = (i=0) => {return (() => (++i) )};
var v = Add();
v();           //1
v();           //2
//由於僅有一個返回,return 及括號()也能夠省略
var Add = (i=0)=> ()=> (++i);

//遞歸
var fact = (x) => ( x==0 ?  1 : x*fact(x-1) );
fact(5);       // 120

主要特色

  • 不綁定this;
  • 不綁定arguments。

不綁定this

  • 在ES5中:每一個函數都有本身的this值,在構造函數中定義的方法,this指向調用這個方法的實例化對象;在全局做用域中調用的方法,this指向window全局對象。
  • 可是,箭頭函數不會建立本身的this,它只會從本身的做用域鏈上一層繼承this(只有在封閉的函數做用域內,才能繼承其this;若是在對象字面量內定義的方法,並不能繼承對象的this,由於大括號{}不能起到封閉的效果)
function Person() {
  this.age = 0;

  setInterval(function growUp() {
    this.age++;//undefined
  }, 1000);
}
var p = new Person();

這個間歇調用函數中定義的growUp回調函數,是在全局做用域下執行的,其this指向全局對象,並非Person構造函數實例對象。
可使用變量緩存來解決:java

function Person() {
  var that=this;
  that.age = 0;
  setInterval(function growUp() {
    that.age++;
  }, 1000);
}
var p = new Person();

箭頭函數,建立之初就綁定了做用域鏈繼承的this,在哪裏調用沒有關係。數組

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| 正確地指向person對象
  }, 1000);
}
var p = new Person();

不綁定arguments

  • 不能在箭頭函數中使用參數數組:arguments
  • 解決辦法:剩餘參數
function foo() { 
  var f = (...args) => args[0]; 
  return f(2); 
}

foo(1); 
// 2

其餘特性

  • call、apply、bind方法在ES5中都是改變函數中this的指向,而箭頭函數沒有本身的this指針,所以,經過以上方法調用一個函數時,只能傳參,忽略第一個參數。
  • 不能用做構造器,和 new一塊兒用會拋出錯誤。
  • 沒有prototype屬性。
  • 不能用做生成器, yield 關鍵字一般不能在箭頭函數中使用。

注意

  • 箭頭函數不能做爲對象的方法使用,除非將它封閉在函數做用域中;
obj = {
    data: ['John Backus', 'John Hopcroft'],
    init: function() {
        document.onclick = ev => {
            alert(this.data) // ['John Backus', 'John Hopcroft']
        }
        // 非箭頭函數
        // document.onclick = function(ev) {
        //     alert(this.data) // undefined
        // }
    }
}
obj.init()
  • 不能做爲構造函數;
  • 不能定義原型方法。
相關文章
相關標籤/搜索