天天看点

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)