【问题标题】:Javascript class methods versus propertiesJavascript 类方法与属性
【发布时间】:2017-11-09 11:22:18
【问题描述】:

我见过使用 Javascript 类的代码使用以下形式(例如 React):

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

  handleOpen = () => {
    this.setState({ open: true })
  }
}

为什么handleOpen 被实现为设置为函数的属性而不是类似的东西:

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

  handleOpen() {
    this.setState({ open: true })
  }
}

提前致谢!

【问题讨论】:

  • 请注意,foo = ... 是一个实验性功能。它还不是任何规范的一部分,当然不是 ES6。
  • @FelixKling,你指的是哪一部分?
  • @Chris:类体内的语法 name = value 以及方法定义 (foo() {})。这目前是一个提议,并不是语言的正式组成部分。见tc39.github.io/proposal-class-public-fields
  • @FelixKling,天哪,我什至没有注意到。但是,我确实认为 OP 只是省略了构造函数以使示例简短。由于使用了箭头函数,我将问题标记为 ES6。
  • @FelixKling 我想的差不多,但我见过的很多 React 代码 sn-ps 都使用这种语法。

标签: javascript reactjs ecmascript-next


【解决方案1】:

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

MDN docs 是这样说的:

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


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

直到箭头函数,每个新函数都定义了自己的 this 值

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

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

【讨论】:

  • 另一个区别是类实例语法(分配箭头函数)为组件的每个实例创建一个新函数。使用类方法语法,所有实例都引用一个函数,并在调用之前为其设置适当的上下文(如原型链)。如果您要在不需要的地方使用类实例语法,您将在运行时创建不需要的函数,并且可能会创建很多函数。
  • @Chris Ross 所说的与函数是否是箭头函数相比,有更大的不同——handleOpen = () => ... 将为此函数分配一个 copy每个类实例。 handleOpen () { ... } 将在UserProfile.prototype 上分配一次。一般来说,应该首选prototype 方法,因为它不会重复函数分配
【解决方案2】:

这与您的方法中 this 的上下文有关。如果您要像第二个示例一样实现它,this 不会引用组件实例,而是使用第一个示例中的箭头函数 this 引用组件实例。 (由于没有使用React.createClass)。

对于第二个示例,您必须在构造函数中执行 this.handleOpen = this.handleOpen.bind(this)

编辑:有关arrow functions 的详细信息,请参阅Chris 的答案。

【讨论】:

  • 谢谢,这是有道理的!
猜你喜欢
  • 1970-01-01
  • 2019-01-25
  • 1970-01-01
  • 2017-07-16
  • 1970-01-01
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多