箭头函数和普通函数的区别

1,262 阅读2分钟

前言:平时看文章逛论坛,都了解箭头函数的特性,开发的时候用到频率也非常多,但到真正问到的时候总是说的不够全面,因此有必要写篇文章总结概括下。

1、普通函数和箭头函数的写法

2、this指向

普通函数的this指向的是执行上下文(动态的),即this的值取决于函数本身如何被调用。常用的有以下4种方式。
第一种是直接调用,this指向全局对象(在严格模式下是undefined)

第二种是作为对象方法调用,this指向方法所属的对象

第三种是动态改变执行上下文的方式调用,即通过.call、.apply和.bind,this指向第一个参数代表的上下文对象。

第四种是作为构造函数调用,this指向通过new关键字创建的实例。

箭头函数的this与普通函数的规则不同。不管用什么方式,怎么调用,箭头函数的this永远指向外层函数的this。注意:外层函数的this是有可能变的。

输出结果:

3、构造函数

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

function Cat (color) {
    this.color = color
}

const cat1 = new Cat('black')
console.log(cat1 instanceof Cat) // true

箭头函数不可以使用new命令,否则会抛出一个错误。

4、arguments对象

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

function myFun () {
    console.log(arguments)
}

myFun(1, 2) // {0: 1, 1: 2}

而箭头函数中没有定义 arguments 关键字,跟this一样,也是由词法决定的,也就是会解析到外层函数的 arguments

function myFun () {
    const a = () => console.log(arguments)
    const b = (...args) => console.log(args)
    a(3, 4) // {0: 1, 1: 2}
    b(3, 4) // [3, 4]
}

myFun(1, 2)

5、成员方法

我们通常用普通函数来定义类的成员方法,当需要把成员方法当成回调函数来用的时候,要访问当前实例 this 就会有问题。比如:

class Coder {
  constructor(nickName) {
    this.nickName = nickName
  }
  logName () { console.log(this.nickName) }
}
const coder = new Coder('Kayson')
setTimeout(coder.logName, 1000)
// 1 秒后输出 undefined

箭头函数里的this直接指向类的实例对象

class Coder {
  constructor(nickName) {
    this.nickName= nickName
  }
  logName = () => console.log(this.nickName)
}
const coder = new Coder('Kayson')
setTimeout(coder.logName, 1000)
// 1 秒后输出 "Kayson"

借鉴

你知道ES6箭头函数的优缺点吗?