Javascript类方法与属性

rhl*_*hrm 7 javascript reactjs ecmascript-next

我已经看到使用Javascript类的代码使用以下形式(示例是React):

class UserProfile extends Component {
  state = {
    open: false
  }

  handleOpen = () => {
    this.setState({ open: true })
  }
}
Run Code Online (Sandbox Code Playgroud)

为什么handleOpen实现为设置为函数的属性,而不是类似以下内容的属性:

class UserProfile extends Component {
  state = {
    open: false
  }

  handleOpen() {
    this.setState({ open: true })
  }
}
Run Code Online (Sandbox Code Playgroud)

提前致谢!

Chr*_*ris 7

这也是一个函数,但它被称为箭头函数,其工作方式与“传统”实现略有不同。它是在 ECMAScript 6 中引入的。

这是MDN 文档所说的:

箭头函数表达式的语法比函数表达式更短,并且不绑定自己的thisargumentssupernew.target。这些函数表达式最适合非方法函数,它们不能用作构造函数。


主要好处之一是您不需要绑定this到该函数,因为箭头函数没有自己的this对象:

在箭头函数之前,每个新函数都定义了自己的 this 值

这保证了范围安全;不可能this偶然使用不正确的。可以说它也稍微更具可读性。

然而,一个缺点是箭头函数是匿名的,这意味着当你的代码出现错误时,很难进行堆栈跟踪。但是对于 React 应用程序,我们可以使用 devtool:'cheap-module-eval-source-map ' 从 babel 中轻松找到堆栈跟踪中的错误。

  • 另一个区别是类实例语法(分配箭头函数)为组件的每个实例创建一个新函数。使用类方法语法,所有实例都引用一个单一的函数,并在调用之前为其设置适当的上下文(如原型链)。如果您要在不需要的地方使用类实例语法,您将在运行时创建不需要的函数,并且可能会创建很多函数。 (3认同)
  • @Chris Ross 所谈论的内容比函数是否是箭头函数有更大的区别 - `handleOpen = () => ...` 将为每个类实例分配该函数的*副本*。`handleOpen () { ... }` 将在 `UserProfile.prototype` 上分配*一次*。一般来说,应该首选“prototype”方法,因为它不会重复函数分配 (3认同)