箭頭函數(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
【推薦】50萬行VC++源碼: 大型組態工控、電力仿真CAD與GIS源碼庫
【推薦】移動直播百強八成都在用融雲即時通信雲
【推薦】報表開發有捷徑:快速設計輕鬆集成,數據可視化和交互
【推薦】網易雲信-一天開發一個微信,首創1對1技術顧問讓開發加速
【推薦】一個小型創業公司怎樣低成本起步?