簡單理解ECMAScript2015中的箭頭函數新特性

箭頭函數(Arrow functions),是ECMAScript2015中新加的特性,它的產生,主要有如下兩個緣由:一是使得函數表達式(匿名函數)有更簡潔的語法,二是它擁有詞法做用域的this值,也就是說它跟父做用域共享this,不會新產生本身做用域下的this, arguments, super 和 new.target 等對象。javascript

使用箭頭函數特性

在JavaScript代碼中,函數無處不在。假設頁面上有一個特定的按鈕,它的id是‘clickMe’,點擊它後,頁面彈出「Hello,Arrow functions!」,爲實現這個效果,咱們會像下面這樣編寫JavaScript代碼:php

$(function(){ $('#clickMe').click(function(){ alert('Hello,Arrow functions!'); }) })

以上是傳統的JavaScript寫法,給click方法傳入一個函數做爲參數,這個函數一般都須要按照如下格式輸入:function(){}。使用箭頭函數後,代碼以下:html

$(function(){ $('#clickMe').click(()=>{alert('Hello,Arrow functions!')}); })

上面的例子比較簡單,再來看一個Promise鏈的例子:java

function getUserInfo(id){ return getUsers(id). then(function(users){return users[0]}). then(checkUser). then(function(user,userInfo){return userInfo }). catch(function(error){console.log(error.message)}) }

使用箭頭函數簡化上面的例子,代碼以下:編程

function getUserInfo(id){ return getUsers(id). then(users => users[0]). then(checkUser). then((user,userInfo)=>userInfo). catch(error=>console.log(error.message)) } 

從簡化後的代碼來看,不難發現,全部回調函數中的function 和 {}不見了,並且回調函數都在一行表示,當只有一個參數時,()也消失了;因爲{}消失了,裏面的return也消失了,代碼看起來更加清晰、簡潔了。前面提到單行表示回調函數的時候,{}被省略了,假如這時候咱們要返回一個對象(包括空對象)的話,該怎麼處理呢?這是個坑,通常按以下方式書寫代碼:微信

const emptyObject = ()=>({})

箭頭函數裏面的this

開頭那裏已經提到了,箭頭函數沒有本身的this值,它跟父做用域共享this,箭頭函數內部也沒有constructor方法,也沒有prototype,因此箭頭函數不支持new操做。markdown

在箭頭函數以前,每一個新定義的函數都有本身的this值,例如,構造函數的this指向一個新的對象,若是是‘嚴格模式’,則this值爲undefined,若是函數做爲對象的方法被調用,則該函數的this指向了那個調用它的對象。在JavaScript面向對象編程中,this的指向是讓新手很頭疼的問題。閉包

function Person(){ //構造函數的this指向實例對象本身 this.age = 25; setInterval(function growUp(){ //在非嚴格模式下,growUp函數定義了其內部的this,其指向window對象,不一樣於構造函數Person()定義的this this.age++; },1000); } var p = new Person();

在箭頭函數以前,咱們是如何使growUp函數內部的this也指向構造函數Person()的實例對象的呢?以下:app

function Person() { var self = this; self.age = 25; setInterval(function growUp(){ self.age++; }); } var p = new Person();

也就是經過新增一個變量來指向指望的this對象,除此以外,還可使用 bind 函數,把指望的 this 值傳遞給 growUp() 函數。ide

function Person() { this.age = 25; setInterval(function growUp(){ this.age++; console.log(this.age); }.bind(this),1000); } var p = new Person();

因爲箭頭函數會捕獲其所在上下文的this值,來做爲本身的this值,因此咱們能夠這樣修改上述例子的代碼:

function Person() { this.age = 25; setInterval(()=>{ this.age++;//這裏的this也指向Person對象 },1000); }

使用 call 或 apply 調用

箭頭函數的 this 始終指向函數定義時的 this,而非執行時。下面看一個試圖改變箭頭函數 this 指針的例子:

var x = 1, o = { x : 10, test : () => this.x }; o.test(); // 1 o.test.call(o); // 仍舊是1

因爲 this 已經在詞法層面完成了綁定,經過 call() 或 apply() 方法調用一個函數時,只是傳入了參數而已,對 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)); // 輸出 2 console.log(adder.addThruCall(1)); // 仍然輸出 2,而不是3
 
 
 
 
 
 
 
相關文章
相關標籤/搜索