箭头函数语法特点详解

123 阅读2分钟

箭头函数语法

基本写法:

(arg1, arg2) => {statements}

规则

  1. 当有参数且只有一个的时候,() 可以省略 x=>{...}
  2. 当函数体只有一个语句的时候,大括号可以不用写,而且 return 也可以省略;
x=>x + 1 // 等于 x=> {return x + 1}
  1. 在简写的单句函数体的情况下,如果返回值是一个对象,需要加上一个 ()
x => ({a: x})

箭头函数语法的主要特点 —— this:

一句话,箭头函数没有 this

普通的函数中的 this,会根据我们执行它的时候的实际情况而改变;但是箭头函数没有 this,this 对它来说就是当前作用域下的一个普通的变量名。

换而言之,当我们写下一个箭头函数的时候,就算没有执行它,它内部的 this 已然确定

所以,当我们在全局环境下写下一个箭头函数的时候,它的 this 就是全局变量 window.

那么,如果我们在一个函数内部写一个箭头函数呢?

let a = 1
let b = {b: 1}
let c = {c: 1}
function normalFn(){
  let arrowFn = () => console.log(this)
  arrowFn()
}

normalFn.call(b)
normalFn.call(c)

为什么两次箭头函数的中 this 不一样呢?那是因为,函数 normalFn 每执行一次的时候,就会创建一个新的作用域,同时会创建一个新的 arrowFn,每个 arrowFn 中的 this 依然是它创建时候代码环境(在这里是局部)下的 this。

基于这个特点:

合适使用箭头函数的地方:

let a = 1
let b = {b: 1}
function normalFn(){
  setTimeout(()=>{console.log(this)}, 100) // → {b: 1}
  setTimeout(function (){console.log(this)}, 100)  // → window
}
normalFn.call(b)

异步代码中的回调函数,如果是普通函数,那么它的回调函数在执行的时候 this 可能会变成 window; 而因为 arrowFn 中 this 是稳定的,所以它的 this 很符合我们的预期。

不合适使用的地方:

值得注意的是,箭头函数考虑的是作用域,所以当我们在一个对象里面使用箭头函数作为方法的时候,它的 this 不是对象,而是对象所在作用域上的 this.

let a = {
  fn: ()=>{console.log(this)}
}
a.fn() // window …

这也是为什么我们在 vue methods 中使用箭头函数的时候,我们得到的 this 不是当前组件,而是 undefined;

与此同时,我们已经不难理解:用call()、apply()、bind()这些方法在箭头函数身上是没用的。

箭头函数的其它特点:

  1. 没有arguments对象;

  2. 不可以当作构造函数;

  3. 箭头函数不能用作 Generator 函数,不可以使用yield命令;

  4. 异步箭头函数是可以的:

async () => {
  // do something
}