Синтаксис класса Javascript и привязка его к методам [дубликат]

Dec 09 2020

Я хотел понять основную разницу между тем, как работает приведенный ниже синтаксис.

// Syntax 1
class Component extends React.Component {
  constructor(props) {
    super(props)
    this.handleClick = this.handleClick.bind(this)
  }

  handleClick() {
    // ...
  }
}

// Syntax 2

handleClick = () => {
  console.log('this is:', this)
}
<button onClick={this.handleClick}>
  {'Click me'}
</button>

Синтаксис 1 требует, чтобы внутри конструктора была указана явная привязка. Однако похоже, что с синтаксисом 2 это не нужно. Как синтаксис 2 может автоматически выполнять привязку?

Я предполагаю, что это понимание / синтаксис может быть расширено для любого фреймворка, включая React, Angular, Ember и т. Д.

Ответы

1 CertainPerformance Dec 09 2020 at 11:52

Поля класса, то есть свойства, определенные непосредственно внутри тела класса, по сути являются синтаксическим сахаром для того же самого внутри конструктора. Итак, это:

class Something {
  handleClick = () => {
    console.log('this is:', this)
  }
}

есть, обессахаренный:

class Something {
  constructor() {
    this.handleClick = () => {
      console.log('this is:', this)
    };
  }
}

После удаления шугаринга должно быть ясно, что происходит - стрелочная функция означает, что thisссылка на то, что thisнаходится в конструкторе, то есть на сам экземпляр, привязка не требуется.

Это не просто React или фреймворк - это стандартные правила в обычном JavaScript.

Если вы не привязываете метод, не используете стрелочную функцию или что-то подобное, тогда:

<button onClick={this.handleClick}>

терпит неудачу по той же причине, что

someButton.addEventListener('click', myObj.someFn)

также не сможет выполнить вызов someFnс контекстом вызова myObj- все, что знает браузер, - это вызвать обратный вызов, переданный прослушивателю кликов; контекст вызова myObjтеряется при такой передаче.