1. 首页
  2. IT资讯

「ES6基础」箭头函数(Arrow functions)

“u003Cdivu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp3.pstatp.comu002Flargeu002Fpgc-imageu002F0c9fd3bf4a5544c295abee58aa578050″ img_width=”900″ img_height=”383″ alt=”「ES6基础」箭头函数(Arrow functions)” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003EES6中,除了let和const新特性,箭头函数是使用频率最高的新特性了。如果你曾经了解如日中天的JavaScript衍生语言CoffeeScript, 就会清楚此特性并非ES6独创。箭头函数顾名思义是使用箭头(=>)定义的函数,属于匿名函数一类。u003Cu002Fpu003Eu003Cpu003E今天的文章内容将会从以下几个方面,介绍箭头函数:u003Cu002Fpu003Eu003Culu003Eu003Cliu003E使用语法u003Cu002Fliu003Eu003Cliu003Ethis穿透u003Cu002Fliu003Eu003Cliu003E箭头函数和传统函数的区别u003Cu002Fliu003Eu003Cu002Fulu003Eu003Cpu003Eu003Cstrongu003E本篇文章阅读时间预计8分钟u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Ch1u003E使用语法u003Cu002Fh1u003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fdfic-imagehandleru002Ff3cb7b3e-512b-40ad-8614-fa7dd3e9e2c8″ img_width=”1023″ img_height=”614″ alt=”「ES6基础」箭头函数(Arrow functions)” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E箭头函数有四种使用语法u003Cu002Fpu003Eu003Cpu003Eu003Cstrongu003E1、单一参数的单行箭头函数u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpu003E如下段代码所示,很简单:u003Cu002Fpu003Eu003Cpreu003Econst fn= foo =>`${foo} world`;u003Cbru003Eu003Cu002Fpreu003Eu003Cpu003E这是箭头函数最简洁的形式,常用于用作简单的处理函数,如过滤。如下段代码所示:u003Cu002Fpu003Eu003Cpreu003Elet array=[‘a’,’bc’,’def’,’ghij’];u003Cbru003Earray=array.filter(item=>item.length>=2);u003Cbru003Eu003Cu002Fpreu003Eu003Cpu003Eu003Cstrongu003E2、多参数的单行箭头函数u003Cu002Fstrongu003E 语法也很简单,如下段代码所示:u003Cu002Fpu003Eu003Cpreu003Econst fn=(foo,bar) => foo+baru003Cbru003Eu003Cu002Fpreu003Eu003Cpu003E在实际开发中,函数的参数不会只有一个,在箭头函数中,多参数的语法跟普通函数一样,用括号包裹参数项。我们经常处理函数,如排序,示例代码如下:u003Cu002Fpu003Eu003Cpreu003Elet array=[‘a’,’bc’,’def’,’ghij’];u003Cbru003Earray=array.sort((a,b) => a.length < b.length);u003Cbru003Eu003Cu002Fpreu003Eu003Cpu003Eu003Cstrongu003E3、多行箭头函数u003Cu002Fstrongu003E 单一参数,如下段代码所示:u003Cu002Fpu003Eu003Cpreu003Efoo => {u003Cbru003E return `${foo} world`;u003Cbru003E}u003Cbru003Eu003Cu002Fpreu003Eu003Cpu003E多参数,如下段代码所示:u003Cu002Fpu003Eu003Cpreu003E(foo,bar) => {u003Cbru003E return foo+bar;u003Cbru003E}u003Cbru003Eu003Cu002Fpreu003Eu003Cpu003Eu003Cstrongu003E4、无参数箭头函数u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpu003E如果一个箭头函数无参数传入,则需要用一对空的括号来表示空的参数列表。u003Cu002Fpu003Eu003Cpreu003Econst greet = () => ‘Hello World’u003Cbru003Eu003Cu002Fpreu003Eu003Cpu003E以上都是被支持的箭头函数的表达方式,其最大的好处就是简单明了,省略了function关键字,而使用 => 代替。相对于传统的function函数,箭头函数在简单的函数使用中更为简洁直观。u003Cu002Fpu003Eu003Cpu003E书写箭头的函数过程中,我们应该注意以下几点:u003Cu002Fpu003Eu003Cpu003Eu003Cstrongu003E1、使用单行箭头函数时,应避免换行u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpu003E错误的用法,如下段代码所示:u003Cu002Fpu003Eu003Cpreu003Econst fn=xu003Cbru003E=> x*2 u002Fu002FSyntaxErroru003Cbru003Eu003Cu002Fpreu003Eu003Cpu003E正确的写法,如下:u003Cu002Fpu003Eu003Cpreu003Econst fn= x => x*2 u002Fu002Foku003Cbru003Eu003Cu002Fpreu003Eu003Cpu003Eu003Cstrongu003E2、参数列别的右括弧、箭头应在一行u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpu003E错误的用法,如下段代码所示:u003Cu002Fpu003Eu003Cpreu003Econst fn = (x,y) u002Fu002FSyntaxErroru003Cbru003E=> {u003Cbru003E return x*y;u003Cbru003E}u003Cbru003Eu003Cu002Fpreu003Eu003Cpu003E下段代码书写是正确的:u003Cu002Fpu003Eu003Cpreu003Econst fn= (x,y) => { u002Fu002Foku003Cbru003E return x*yu003Cbru003E}u003Cbru003Econst fn= (x,u003Cbru003E y) => { u002Fu002Foku003Cbru003E return x*y u003Cbru003E}u003Cbru003Eu003Cu002Fpreu003Eu003Cpu003Eu003Cstrongu003E3、单行箭头函数返回只能包含一条语句u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpu003E错误的书写,如下段代码所示:u003Cu002Fpu003Eu003Cpreu003Econst fn1= x => x=x*2; return x+2; u002Fu002FSyntaxErroru003Cbru003Eu003Cu002Fpreu003Eu003Cpu003E正确的书写,如下段代码所示:u003Cu002Fpu003Eu003Cpreu003Econst fn2= x => {u003Cbru003E x=x*2;u003Cbru003E return x+2;u003Cbru003E} u002Fu002Foku003Cbru003Eu003Cu002Fpreu003Eu003Cpu003Eu003Cstrongu003E4、如果单行箭头返回一个对象,请用圆括号包裹u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpu003E错误的书写,如下段代码所示,解析引擎会将其解析成一个多行箭头函数:u003Cu002Fpu003Eu003Cpreu003Econst ids=[1,2,3];u003Cbru003Econst users=ids.map(id=>{id:id});u003Cbru003Eu002Fu002Fwrong:[ undefined, undefined, undefined ]u003Cbru003Eu003Cu002Fpreu003Eu003Cpu003E正确的书写,如下段代码所示:u003Cu002Fpu003Eu003Cpreu003Econst ids=[1,2,3];u003Cbru003Econst users=ids.map(id=>({id:id}));u003Cbru003Eu002Fu002FCorrect:[ { id: 1 }, { id: 2 }, { id: 3 } ]u003Cbru003Eu003Cu002Fpreu003Eu003Cpu003E箭头函数十分简洁,特别适合单行回调函数的定义,比如我们有以下需求:u003Cu002Fpu003Eu003Cpu003E我们有一个这样的名字数组names,[‘Will’,’Jack’,’Peter’,’Steve’,’John’,’Hugo’,’Mike’],输出序号为偶数的名字[ ‘Will’, ‘Peter’, ‘John’, ‘Mike’ ],我们如何使用箭头函数在一行语句完成呢,如下段代码所示:u003Cu002Fpu003Eu003Cpreu003Econst names=[‘Will’,’Jack’,’Peter’,’Steve’,’John’,’Hugo’,’Mike’];u003Cbru003Econst newSet=namesu003Cbru003E.map((name,index)=>({u003Cbru003E id:index,u003Cbru003E name:nameu003Cbru003E}))u003Cbru003E.filter(man => man.id %2 ==0)u003Cbru003E.map(man => [man.name])u003Cbru003E.reduce((a,b) => a.concat(b))u003Cbru003Eu003Cu002Fpreu003Eu003Ch1u003Ethis穿透u003Cu002Fh1u003Eu003Cpu003E事实上,箭头函数不仅书写简洁,还有一个神奇的功能,就是将函数内部的this延伸上一层作用域中(绑定最近的非箭头函数的上下文),及上一层的上下文会穿透到内层的箭头函数中,让我们先看一段实际的例子,如下段所示:u003Cu002Fpu003Eu003Cpreu003Evar Widget={u003Cbru003E u002Fu002F Au003Cbru003E init:function () {u003Cbru003E u002Fu002F Bu003Cbru003E document.addEventListener(“click”, function (event){u003Cbru003E u002Fu002FCu003Cbru003E this.doSomething(event.type);u003Cbru003E }, false);u003Cbru003E },u003Cbru003E doSomething:function (type) {u003Cbru003E console.log(“Handling”+ type+”event”);u003Cbru003E }u003Cbru003E};u003Cbru003EWidget.init();u003Cbru003Eu003Cu002Fpreu003Eu003Cpu003E这段代码会如何输出呢,想必大家都猜到了吧,输出undefined,为什么呢?我们在B位置内声明了函数(C区域),this关键词的指向B区域的函数,由于B区域内没有doSomething函数声明,因此输出undefined,ES6之前我们如何修正此问题呢?u003Cu002Fpu003Eu003Cpu003E我们可以使用bind方法改变this指向A区域Widget对象,示例代码如下:u003Cu002Fpu003Eu003Cpreu003Evar Widget={u003Cbru003E u002Fu002F Au003Cbru003E init:function () {u003Cbru003E u002Fu002F Bu003Cbru003E document.addEventListener(“click”, (function (event) {u003Cbru003E u002Fu002FCu003Cbru003E this.doSomething(event.type);u003Cbru003E }).bind(this), false);u003Cbru003E },u003Cbru003E doSomething:function (type) {u003Cbru003E console.log(“Handling”+ type+”event”);u003Cbru003E }u003Cbru003E};u003Cbru003EWidget.init();u003Cbru003Eu003Cu002Fpreu003Eu003Cpu003E下面这种方法是我们最常用的方法,我们在B区域声明了that变量,并将其this赋值,确保c区域this的指向至Widget对象:u003Cu002Fpu003Eu003Cpreu003Evar Widget={u003Cbru003E u002Fu002F Au003Cbru003E init:function () {u003Cbru003E u002Fu002F Bu003Cbru003E var that=this;u003Cbru003E document.addEventListener(“click”, function (event) {u003Cbru003E u002Fu002FCu003Cbru003E that.doSomething(event.type);u003Cbru003E console.log(that);u003Cbru003E }, false);u003Cbru003E },u003Cbru003E doSomething:function (type) {u003Cbru003E console.log(“Handling”+ type+”event”);u003Cbru003E }u003Cbru003E};u003Cbru003EWidget.init();u003Cbru003Eu003Cu002Fpreu003Eu003Cpu003E有了箭头函数,我们可以使用箭头函数的this穿透功能,将this的作用域延伸至上一层B区域函数,绑定最近的非箭头函数的上下文,如下段代码所示:u003Cu002Fpu003Eu003Cpreu003Evar Widget={u003Cbru003Eu002Fu002FAu003Cbru003E init:function () {u003Cbru003E u002Fu002FBu003Cbru003E document.addEventListener(“click”, (event) => {u003Cbru003E u002Fu002FCu003Cbru003E this.doSomething(event.type);u003Cbru003E }, false);u003Cbru003E },u003Cbru003E doSomething:function (type) {u003Cbru003E console.log(“Handling”+ type+”event”);u003Cbru003E }u003Cbru003E};u003Cbru003EWidget.init();u003Cbru003Eu003Cu002Fpreu003Eu003Cpu003E箭头函数是不是更简单,代码更清晰呢。u003Cu002Fpu003Eu003Cpu003E还有一个情况需要注意,箭头函数对上下文的绑定是强制的,无法通过call或aplly进行改变,如下段代码所示:u003Cu002Fpu003Eu003Cpreu003Efunction widget() {u003Cbru003E this.id=123;u003Cbru003E this.log=()=>{u003Cbru003E console.log(this)u003Cbru003E console.log(‘widget log’,this.id);u003Cbru003E }u003Cbru003E}u003Cbru003Evar pseudoWidget={u003Cbru003E id:456u003Cbru003E};u003Cbru003Enew widget().log.call(pseudoWidget);u002Fu002F123u003Cbru003Eu003Cu002Fpreu003Eu003Cpu003E上述代码会如何输出呢,由于箭头函数对上下文的绑定是强制的,因此this指向不会指向pseudoWidget对象,因此输出123。u003Cu002Fpu003Eu003Ch1u003E箭头函数和传统函数的区别u003Cu002Fh1u003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fdfic-imagehandleru002F0043c77e-29a9-4cc0-a67f-540676bf3629″ img_width=”1023″ img_height=”685″ alt=”「ES6基础」箭头函数(Arrow functions)” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003Eu003Cstrongu003E1、箭头函数作为匿名函数,是不能作为构造函数的,不能使用newu003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpu003E如下段代码所示,我们使用new方法,会提示如下信息:u003Cu002Fpu003Eu003Cpreu003Econst B =()=>({wechat:”前端达人”});u003Cbru003Elet b = new B(); u002Fu002FTypeError: B is not a constructoru003Cbru003Eu003Cu002Fpreu003Eu003Cpu003Eu003Cstrongu003E2、箭头函数不绑定arguments,可以使用剩余参数(rest)解决u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpreu003Efunction A(a){u003Cbru003E console.log(arguments); u002Fu002F[object Arguments] {0: 1}u003Cbru003E}u003Cbru003Evar B = (b)=>{u003Cbru003E console.log(arguments); u002Fu002FReferenceError: arguments is not definedu003Cbru003E}u003Cbru003Evar C = (…c)=>{ u002Fu002F…c即为rest参数u003Cbru003E console.log(c); u002Fu002F[3]u003Cbru003E}u003Cbru003EA(1);u003Cbru003EB(2);u003Cbru003EC(3);u003Cbru003Eu003Cu002Fpreu003Eu003Cpu003Eu003Cstrongu003E3、箭头函数this指向具备穿透特性,会捕获其所在上下文的this值u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpu003Eu003Cstrongu003E4、箭头函数没有原型属性u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpreu003Evar a = ()=>{u003Cbru003E return ‘前端达人’;u003Cbru003E}u003Cbru003Efunction b(){u003Cbru003E return ‘前端达人’;u003Cbru003E}u003Cbru003Econsole.log(a.prototype);u002Fu002Fundefinedu003Cbru003Econsole.log(b.prototype);u002Fu002Fobject{…}u003Cbru003Eu003Cu002Fpreu003Eu003Cpu003Eu003Cstrongu003E5、箭头函数不能当做Generator函数,不能使用yield关键字u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpu003Eu003Cstrongu003E6、箭头函数对上下文的绑定是强制的,无法通过call或aplly进行改变u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpu003E小节u003Cu002Fpu003Eu003Cpu003E今天的内容就介绍到这里,我们可以看出使用箭头函能减少代码量,更加简介易读。在使用箭头函数时,我们一定要理解箭头函数和传统函数的区别,如果函数功能简单,只是简单的逻辑处理,尽量使用箭头函数。u003Cu002Fpu003Eu003Cpu003E更多精彩内容,请微信关注u003Cstrongu003E”前端达人”公众号u003Cu002Fstrongu003E!u003Cu002Fpu003Eu003Cu002Fdivu003E”

原文始发于:「ES6基础」箭头函数(Arrow functions)

主题测试文章,只做测试使用。发布者:杀手梦三刀,转转请注明出处:http://www.cxybcw.com/10776.html

联系我们

13687733322

在线咨询:点击这里给我发消息

邮件:1877088071@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code