Składnia klasy JavaScript i powiązanie jej z metodami [duplikat]

Dec 09 2020

Chciałem zrozumieć podstawową różnicę między sposobem działania poniższej składni.

// 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>

Podczas gdy składnia 1 wymaga wyraźnego powiązania, które należy określić wewnątrz konstruktora. Jednak wydaje się, że przy składni 2 nie jest to potrzebne. W jaki sposób składnia 2 może automatycznie uzyskać powiązanie?

Zakładam, że to zrozumienie / składnia można rozszerzyć na dowolny framework, w tym React, Angular, Ember itp

Odpowiedzi

1 CertainPerformance Dec 09 2020 at 11:52

Pola klas - to znaczy właściwości zdefiniowane bezpośrednio w treści klasy - są po prostu cukrem składni dla tego samego elementu wewnątrz konstruktora. Więc to:

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

jest pozbawiony cukru:

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

Po usunięciu cukrowania powinno być jasne, co się dzieje - funkcja strzałki oznacza, że thisodwołuje się do tego, co thisjest w konstruktorze, czyli samej instancji, nie jest potrzebne żadne wiązanie.

To nie jest tylko kwestia Reacta czy frameworka - są to standardowe reguły w waniliowym JavaScript.

Jeśli nie powiążesz metody, nie użyjesz funkcji strzałkowej lub czegoś podobnego, to:

<button onClick={this.handleClick}>

zawodzi z tego samego powodu

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

również nie zadzwoni someFnz kontekstem wywołania myObj- wszystko, co przeglądarka zna, to wywołanie wywołania zwrotnego przekazanego do nasłuchiwania kliknięć; kontekst wywołania myObjgubi się, gdy jest przekazywany w ten sposób.