Syntaxe de classe Javascript et liaison dans les méthodes [duplicate]

Dec 09 2020

Je voulais comprendre la différence fondamentale entre le fonctionnement de la syntaxe ci-dessous.

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

Alors que la syntaxe 1 a besoin d'une liaison explicite à spécifier dans le constructeur. Cependant, il semble que la syntaxe 2 ne soit pas nécessaire. Comment la syntaxe 2 est-elle capable de réaliser la liaison automatiquement?

Je suppose que cette compréhension / syntaxe peut être étendue pour n'importe quel cadre, y compris React, Angular, Ember, etc.

Réponses

1 CertainPerformance Dec 09 2020 at 11:52

Les champs de classe - c'est-à-dire les propriétés définies directement dans le corps de la classe - ne sont essentiellement que du sucre de syntaxe pour la même chose à l'intérieur du constructeur. Donc ça:

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

est, désucré:

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

Avec le sucre supprimé, il devrait être clair ce qui se passe - la fonction de flèche signifie que le thisfait référence à ce qui thisest dans le constructeur, qui est l'instance elle-même, aucune liaison n'est nécessaire.

Ce n'est pas seulement une chose de React ou de framework - ce sont des règles standard en JavaScript vanilla.

Si vous ne liez pas la méthode ou n'utilisez pas une fonction de flèche ou quelque chose comme ça, alors:

<button onClick={this.handleClick}>

échoue pour la même raison que

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

échouera également à appeler someFnavec un contexte d'appel de myObj- tout ce que le navigateur sait, c'est d'appeler le rappel passé à l'écouteur de clic; le contexte d'appel de myObjse perd lorsqu'il est passé comme ça.