天天看點

es6 filter函數的用法_【ES6基礎】箭頭函數(Arrow functions)

es6 filter函數的用法_【ES6基礎】箭頭函數(Arrow functions)

開篇

ES6中,除了let和const新特性,箭頭函數是使用頻率最高的新特性了。如果你曾經了解如日中天的JavaScript衍生語言CoffeeScript, 就會清楚此特性并非ES6獨創。箭頭函數顧名思義是使用箭頭(=>)定義的函數,屬于匿名函數一類。

今天的文章内容将會從以下幾個方面,介紹箭頭函數:

  • 使用文法
  • 書寫注意事項
  • 使用舉例
  • this穿透
  • 箭頭函數和傳統函數的差別

本篇文章閱讀時間預計8分鐘

01

使用文法

1、單一參數的單行箭頭函數

如下段代碼所示,很簡單:

const fn= foo =>`${foo} world`;
           

這是箭頭函數最簡潔的形式,常用于用作簡單的處理函數,如過濾。如下段代碼所示:

let array=['a','bc','def','ghij'];array=array.filter(item=>item.length>=2);
           

2、多參數的單行箭頭函數

文法也很簡單,如下段代碼所示:

const fn=(foo,bar) => foo+bar;
           

在實際開發中,函數的參數不會隻有一個,在箭頭函數中,多參數的文法跟普通函數一樣,用括号包裹參數項。我們經常處理函數,如排序,示例代碼如下:

let array=['a','bc','def','ghij'];array=array.sort((a,b) => a.length < b.length);
           

3、多行箭頭函數

單一參數,如下段代碼所示:

foo => {    return `${foo} world`;}
           

多參數,如下段代碼所示:

(foo,bar) => {    return foo+bar;}
           

4、無參數箭頭函數

如果一個箭頭函數無參數傳入,則需要用一對空的括号來表示空的參數清單。

const greet = () => 'Hello World';
           

以上都是被支援的箭頭函數的表達方式,其最大的好處就是簡單明了,省略了function關鍵字,而使用 => 代替。相對于傳統的function函數,箭頭函數在簡單的函數使用中更為簡潔直覺。

02

書寫注意事項

1、使用單行箭頭函數時,應避免換行

錯誤的用法,如下段代碼所示:

const fn=x    => x*2 ;//SyntaxError
           

正确的寫法,如下:

const fn= x => x*2;//ok
           

2、參數列别的右括弧、箭頭應在一行

錯誤的用法,如下段代碼所示:

const fn = (x,y) //SyntaxError    => {    return x*y;};
           

下段代碼書寫是正确的:

const fn= (x,y) => { //ok    return x*y}const fn= (x,           y) => { //ok    return x*y}
           

3、單行箭頭函數傳回隻能包含一條語句

錯誤的書寫,如下段代碼所示:

const fn1= x => x=x*2; return x+2; //SyntaxError
           

正确的書寫,如下段代碼所示:

const fn2= x => {    x=x*2;    return x+2;}; //ok
           

4、如果單行箭頭傳回對象,用圓括号包裹

錯誤的書寫,如下段代碼所示,解析引擎會将其解析成一個多行箭頭函數:

const ids=[1,2,3];const users=ids.map(id=>{id:id});//wrong[ undefined, undefined, undefined ]
           

正确的書寫,如下段代碼所示:

const ids=[1,2,3];const users=ids.map(id=>({id:id}));//Correct:[ { id: 1 }, { id: 2 }, { id: 3 } ]
           

03

使用舉例

箭頭函數十分簡潔,特别适合單行回調函數的定義,比如我們有以下需求:

我們有一個這樣的名字數組names=['Will','Jack','Peter','Steve','John','Hugo','Mike'],輸出序号為偶數的名字[ 'Will', 'Peter', 'John', 'Mike' ],我們如何使用簡潔的箭頭文法呢?如下段代碼所示:

const names=['Will','Jack','Peter','Steve','John','Hugo','Mike'];const newSet=names    .map((name,index)=>({        id:index,        name:name    }))    .filter(man => man.id %2 ==0)    .map(man => [man.name])    .reduce((a,b) => a.concat(b));
           

04

this穿透

事實上,箭頭函數不僅書寫簡潔,還有一個神奇的功能,就是将函數内部的this延伸上一層作用域中,介紹之前,先讓我們一起看下如下代碼:

var Widget={    // A    init:function () {        // B        document.addEventListener("click", function (event){            //C            this.doSomething(event.type);        }, false);    },    doSomething:function (type) {        console.log("Handling"+ type+"event");    }};Widget.init();
           

這段代碼會如何輸出呢,想必大家都猜到了吧,輸出undefined,為什麼呢?我們在B位置内聲明了函數(C區域),this關鍵詞的指向B區域的函數,由于B區域内沒有doSomething函數聲明,是以輸出undefined,ES6之前我們如何修正此問題呢?

方法一:我們可以使用bind方法改變this指向A區域Widget對象,示例代碼如下:

var Widget={    // A    init:function () {        // B        document.addEventListener("click", (function (event) {            //C            this.doSomething(event.type);        }).bind(this), false);    },    doSomething:function (type) {        console.log("Handling"+ type+"event");    }};Widget.init();
           

方法二:這種方法是我們最常用的方法,我們在B區域聲明了that變量,并将其this指派,確定c區域this的指向至Widget對象:

var Widget={    // A    init:function () {        // B        var that=this;        document.addEventListener("click", function (event) {            //C            that.doSomething(event.type);            console.log(that);        }, false);    },    doSomething:function (type) {        console.log("Handling"+ type+"event");    }};Widget.init();
           

有了箭頭函數,我們可以使用箭頭函數的this穿透功能特性,将this的作用域延伸至上一層B區域函數,如下段代碼所示:

var Widget={    //A    init:function () {        //B        document.addEventListener("click", (event) => {            //C            this.doSomething(event.type);        }, false);    },    doSomething:function (type) {        console.log("Handling"+ type+"event");    }};Widget.init();
           

箭頭函數是不是更簡單,代碼更清晰呢。

還有一個情況需要注意,箭頭函數對上下文的綁定是強制的,無法通過call或aplly進行改變,如下段代碼所示:

function widget() {    this.id=123;    this.log=()=>{        console.log('widget log',this.id);    }}var pseudoWidget={    id:456};new widget().log.call(pseudoWidget);
           

上述代碼會如何輸出呢?由于箭頭函數對上下文的綁定是強制的,是以this指向不會指向pseudoWidget對象,還是保持widget的函數作用域,是以輸出123。

05

箭頭函數和傳統函數的差別

1、箭頭函數作為匿名函數,是不能作為構造函數的,不能使用new

如下段代碼所示,我們使用new方法,會提示如下資訊:

const B =()=>({wechat:"前端達人"});let b = new B(); //TypeError: B is not a constructor
           

2、箭頭函數不綁定arguments,可以使用剩餘參數(rest)解決

筆者在《【ES6基礎】展開文法(Spread syntax)》文章裡介紹過剩餘參數,這裡就不過多介紹,不清楚的可以點選文章連結進行檢視。如下段代碼所示:

function A(a){    console.log(arguments); //[object Arguments] {0: 1}}var B = (b)=>{    console.log(arguments); //ReferenceError: arguments is not defined};var C = (...c)=>{ //...c即為rest參數    console.log(c); //[3]};A(1);B(2);C(3);
           

3、箭頭函數this指向具備穿透特性,會捕獲其所在上下文的this值

4、箭頭函數沒有原型屬性

var a = ()=>{    return '前端達人';};function b(){    return '前端達人';}console.log(a.prototype);//undefinedconsole.log(b.prototype);//object{...}
           

5、箭頭函數不能當做Generator函數,不能使用yield關鍵字

6、箭頭函數對上下文的綁定是強制的,無法通過call或aplly進行改變

06

小節

今天的内容就介紹到這裡,我們可以看出使用箭頭函能減少代碼量,更加簡潔易讀。在使用箭頭函數時,我們一定要了解箭頭函數和傳統函數的差別,如果函數功能簡單,隻是簡單的邏輯處理,盡量使用箭頭函數。

往期

熱點

文章

es6 filter函數的用法_【ES6基礎】箭頭函數(Arrow functions)
es6 filter函數的用法_【ES6基礎】箭頭函數(Arrow functions)

《【ES6基礎】let和作用域》

《【ES6基礎】const介紹》

《【ES6基礎】預設參數值》

《【ES6基礎】展開文法(Spread syntax)》

《【ES6基礎】解構指派(destructuring assignment)》

《JS加載慢?谷歌大神帶你飛!(文末送電子書)》

《19年你應該關注這50款前端熱門工具(上)》

《19年你應該關注這50款前端熱門工具(中)》

《19年你應該關注這50款前端熱門工具(下)》

《JavaScript基礎——前端不懂它,會再多架構也不過隻是會用而已!》

《JavaScript基礎——你真的了解JavaScript嗎?》

《JavaScript基礎——回調(callback)是什麼?》

《JavaScript基礎——Promise使用指南》

《JavaScript基礎——深入學習async/await》

專注分享當下最實用的前端技術。關注前端達人,與達人一起學習進步!

長按關注"前端達人"

es6 filter函數的用法_【ES6基礎】箭頭函數(Arrow functions)
es6 filter函數的用法_【ES6基礎】箭頭函數(Arrow functions)