箭头函数有哪些特性

什么是箭头函数,如何使用

  ECMAScript 6新增了使用胖箭头(=>)语法定义函数表达式的能力。很大程度上,箭头函数实例化的函数对象与正式的函数表达式创建的函数对象行为是相同的。何可以使用表达式的地方,都可以使用箭头函数

let arrowSum = (a,b)=>{
    return a + b;
}
let functionExpressionSum = function(a,b){
    return a+ b;
}
console.log(arrowSum(3,5)); //8
console.log(functionExpressionSum(3,5)); //8

  箭头函数简洁的语法非常适合嵌入函数的场景

let ints=[1,2,3]
console.log(ints.map(function(i){return i+1})); //[2, 3, 4]
console.log(ints.map((i)=>{return i+1})); //[2, 3, 4]

  如果只有一个参数,那也可以不用括号。只有没有参数,或者多个参数的情况下,才需要使用括号

// 一下两种写法都有效  
let double = (x)=>{
    return 2*x;
}
let triple = x=>{
    return 3*x
}
// 没有参数需要括号  
let getRandom = ()=>{
    return Math.random();
}
// 多个参数需要括号
let sun = (a,b)=>{
    return a+b;
}
// 无效写法  
let multiply = a,b=>{  //Unexpected token '=>'
    return a,b
}

  箭头函数也可以不使用大括号,但这样会改变函数的行为。使用大括号就说明包含“函数体”,可以在一个函数中包含多条语句,跟常规函数一样。如果不使用大括号,那么箭头函数就只能有一行代码,比如一个赋值操作,或者一个表达式。而且,省略大括号会隐式返回这行代码的值。

// 以下两种方法都有效,且返回相应的值  
let double  =(x)=>{
    return x*2;
}
let triple = (x)=>3*x

// 可以赋值
let value = {}
let setName = (x)=>x.name = "Matt"
setName(value);
console.log(value.name); //Matt

// 无效写法 
let multiply = (a,b)=>return a*b  //Unexpected token 'return'

  箭头函数虽然语法简介,但也有很多场合不适用。箭头函数不能使用argumentsupernew,target,也不能用作构造函数。此外,箭头函数也没有prototype属性。

以上内容摘抄自红宝书第四版288页

特性

1. this指向

  常规函数里的this (即执行上下文)指向是动态的。这也是面试常考问题之一。动态的意思就是,this的值取决于函数本身如何被调用。JavaScript里调用常规函数通常有4种方式:

  1. 直接调用this指向全局对象(严格模式下是undefined)
function func(){
    console.log(this);
}
func(); //Window对象
  1. 作为对象方法调用,this指向方法所属对象
let obj = {
    method(){
        console.log(this);
    }
}
obj.method(); //{method: ƒ}
  1. 动态改变执行上下文的方式调用,即通过.call.applythis指向第一个参数代表的上下文对象
function fun(){
    console.log(this);
}

let obj = {value:"Mgd"};
fun.call(obj) //{value: "Mgd"}
fun.apply(obj) //{value: "Mgd"}
  1. 作为构造函数调用。this指向通过new关键字创建的实例
function Func() {
    console.log(this);
}
let newFun = new Func()
newFun(); //Func {}

  箭头函数的this跟常规函数的规则完全不同。无论用什么方式、在哪里调用箭头函数,里面的this永远是外层函数的this。也就是说,箭头函数的this是由词法决定的,它没有定义自己的执行上下文。

let obj = {
    myFunc(items){
        console.log(this)
        let callback = ()=>{
            console.log(this);
        };
        items.forEach(callback)
    }
}
obj.myFunc([1,2,3])

在这里插入图片描述
  在上面的代码中,myFunc()就是箭头函数callback()的外层函数,箭头函数里的this等于外层函数的this,也就是myFunc()
  综上所述,由词法决定this的指向,是箭头函数非常使用的特性之一。在方法里使用回调函数就很方便,this指向很明确,不用去写替换this和绑定this的方法了。

2. 构造函数

  常规函数可作为类的构造函数,用于创建实例

function Person(name){
    this.name = name
}
let man = new Person("Mgd")
console.log(man instanceof Person); //true
let Person= (name)=>{
    this.name = name
}

let man = new Person("Mgd") //Person is not a constructor
console.log(man instanceof Person);

  我们知道箭头函数的this指向由词法决定,没有自己的指向上下文,所以不能做构造函数,如果对箭头函数使用new关键字,会报错。

3. arguments

  常规函数中,arguments是一个类数组对象,包含了函数在执行时接收到的参数列表

function fun(){
    console.log(arguments);
}

fun(1,2)

在这里插入图片描述

function fun(){
    let newFun = ()=>{
        console.log(arguments);
    }
    newFun(3,4)
}
fun(1,2)

在这里插入图片描述
  箭头函数中没有定义arguments 关键字,跟this一样,也是由词法决定的,也就是会解析到外层函数的arguments
  如果想获取箭头函数自己的参数对象,可以用ES6的剩余参数(…操作符)特性

function func(){
    let arrwoFun = (...args)=>{
        console.log(args); //[3, 4]
    }
    arrwoFun(3,4)
}
func(1,2)

4. 隐式返回值

  对于常规函数,需要用return语句返回一个值

function myFunction() {
  return 42;
}

console.log(myFunction()); //42

  如果没有return语句,或者return语句后面没有带表达式,常规函数会隐式返回undefine

function myEmptyFunction() {
  42;
}

function myEmptyFunction2() {
  42;
  return;
}

console.log(myEmptyFunction()); //undefined
console.log(myEmptyFunction2()); //undefined

  箭头函数除了可以用常规函数一样的方式返回值之外,还有一个独有的特性:如果箭头函数只包含一个表达式,那么就可以省略函数体的花括号和return语句,并且这个表达式会被当作返回值

let increment = (num) => num + 1;
console.log(increment(41)); //42

5. 类的成员方法

  通常用常规函数来定义类的成员方法

class Person {
  constructor(name) {
    this.name = name;
  }
  logName() {
    console.log(this.name);  
  }
}

let person = new Person('Mgd');

  但有时候我们需要把成员方法当成回调函数来用,比如setTimeout()回调或者事件监听器。这个时候,如果要访问当前实例this就会有问题了
  比如,我们把logName()方法当作 setTimeout()的回调函数

setTimeout(person.logName.bind(person), 2000); //Mgd

  每个方法都需要手动绑定this执行上下文,很麻烦,可以使用箭头函数作为成员方法
  箭头函数里的this直接指向类的实例对象

class Person {
  constructor(name) {
    this.name= name;
  }

  logName = () => {
    console.log(this.name); 
  }
}

let  person = new Person('Mgd');
setTimeout(person.logName, 2000); //Mgd

  现在person.logName作为回调函数不再需要手动绑定this执行上下文,它总是指向当前类的实例

特性总结

  1. 箭头函数的this指向永远是外层函数的this
  2. 由于this指向的问题,箭头函数不能做构造函数
  3. 箭头函数中没有定义arguments关键字,会解析到外层函数的arguments,想获取箭头函数的参数可以用ES6的剩余参数(…操作符)特性
  4. 如果箭头函数只包含一个表达式,那么就可以省略函数体的花括号和return语句,并且这个表达式会被当作返回值
  5. 箭头函数作为类成员方法,箭头函数里的this直接指向类的实例对象,不需要手动绑定this指向

参考文章:
红宝书第四版288页
知乎:ES6 箭头函数大起底:熟知这几个特点让你少踩很多坑

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值