Skip to content

JavaScript箭头函数介绍

语法

为了理解箭头函数的语法,我们可以逐步重构一个普通函数:

function square(a) {
  return a * a;
}

我们可以从重构函数声明开始,使用变量赋值:

const square = function (a) {
  return a * a;
}

然后,我们可以将普通的function重构为箭头函数:

const square = (a) => {
  return a * a;
}

如果只有一个参数,我们可以省略括号:

const square = a => {
  return a * a;
}

如果函数只有一个表达式,你可以省略花括号和return语句,并使用隐式返回:

const square = a => a * a;

执行上下文

箭头函数和普通函数之间的主要区别在于执行上下文(即this的值)。从技术上讲,其他经常提到的差异要么源于这个差异,要么是它的副作用。

在普通函数中,this是动态的,取决于函数的调用方式:

function simple() { return this; }
const object = {
  method() { return this; }
};
class Class {
  classMethod() { console.log(this); }
}
const instance = new Class();

simple();                   // `this`指向全局对象
new simple();               // `this`指向新创建的实例

object.method();            // `this`指向`object`
simple.call(object);        // `this`指向`object`

instance.classMethod();     // `this`指向`instance`
setTimeout(
  instance.classMethod, 0   // `this`指向全局对象
);

与普通函数不同,箭头函数不定义自己的执行上下文,因此箭头函数内部的this始终指向词法this(即箭头函数定义所在的作用域)。

const simple = () => this;
const object = {
  method: () => this
};
class Class {
  classMethod = () => { console.log(this); }
}
const instance = new Class();

simple();                   // `this` 指向全局对象
new simple();               // 抛出 TypeError: simple 不是一个构造函数

object.method();            // `this` 指向全局对象
simple.call(object);        // `this` 指向全局对象

instance.classMethod();     // `this` 指向 `instance`
setTimeout(
  instance.classMethod, 0   // `this` 指向 `instance`
);

从这些例子中可以看出,由于执行上下文和解析方式的不同,构造函数的工作方式有所不同。与箭头函数不同,普通函数可以用作构造函数,否则会抛出 TypeError

此外,当用于定义类方法时,箭头函数和普通函数也有一些区别。当作为回调函数传递时,普通函数方法会具有不同的执行上下文。可以使用 Function.prototype.bind() 来处理这个问题,或者使用箭头函数,因为箭头函数没有这个问题。

如果您想了解更多关于 this 关键字的内容,可以查看我们的之前的文章