Je regarde du code ES6 et je ne comprends pas ce que fait le symbole @ lorsqu'il est placé devant une variable. La chose la plus proche que j'ai pu trouver a quelque chose à voir avec les champs privés?
Code que je regardais de la bibliothèque redux :
import React, { Component } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'redux/react';
import Counter from '../components/Counter';
import * as CounterActions from '../actions/CounterActions';
@connect(state => ({
counter: state.counter
}))
export default class CounterApp extends Component {
render() {
const { counter, dispatch } = this.props;
return (
<Counter counter={counter}
{...bindActionCreators(CounterActions, dispatch)} />
);
}
}
Voici un article de blog que j'ai trouvé sur le sujet: https://github.com/zenparsing/es-private-fields
Dans ce billet de blog, tous les exemples sont dans le contexte d'une classe - qu'est-ce que cela signifie lorsque le symbole est utilisé dans un module?
C'est un décorateur. C'est une proposition à ajouter à ECMAScript. Il existe plusieurs exemples équivalents ES6 et ES5 sur: javascript-decorators .
Les décorateurs modifient dynamiquement la fonctionnalité d'une fonction, d'une méthode ou d'une classe sans avoir à utiliser directement des sous-classes ou à changer le code source de la fonction en cours de décoration.
Ils sont couramment utilisés pour contrôler l'accès, l'enregistrement, l'annotation.
J'ai trouvé que la réponse acceptée n'était pas suffisante pour m'aider à trier cela, alors j'ajoute un peu plus de détails pour aider ceux qui trouvent cela.
Le problème est qu'il n'est pas clair exactement quel est le décorateur. Le décorateur dans l'exemple donné n'est pas seulement le @
symbole, c'est le @connect
une fonction. Autrement dit, le @connect
la fonction est décoration la classe CounterApp
.
Et que fait-il dans ce cas? C'est connecter le state.counter
valeur pour les accessoires de la classe. N'oubliez pas qu'en redux, la fonction connect
prend deux arguments: mapStateToProps
et mapDispatchToProps
. Dans cet exemple, il ne prend qu'un seul argument - mapStateToProps
.
Je n'ai pas trop étudié cela, mais cela semble être un moyen d'encapsuler vos mappages état-à-accessoires et répartition-à-accessoires afin qu'ils accompagnent vos composants plutôt que d'être situés dans un fichier différent.
@myDecorator()
?Le @
le symbole en javascript représente un décorateur. Les décorateurs ne sont pas présents dans ES6
donc le code in avec lequel vous travaillez avec le décorateur est probablement transposé en une version de javascript qui peut être exécutée dans n'importe quel navigateur.
Un décorateur étend (c.-à-d. Décore) le comportement d'un objet de manière dynamique. La possibilité d'ajouter un nouveau comportement lors de l'exécution est réalisée par un objet Decorator qui "s'enroule" autour de l'objet d'origine. Un décorateur n'est pas seulement un concept en javascript. C'est un modèle de conception utilisé dans tous les langages de programmation orientés objet. Voici une définition de wikipedia:
Dans la programmation orientée objet, le motif décorateur est un motif de conception qui permet d'ajouter un comportement à un objet individuel, dynamiquement, sans affecter le comportement d'autres objets du même classe. Le modèle de décorateur est souvent utile pour adhérer au principe de responsabilité unique, car il permet de diviser la fonctionnalité entre les classes avec des domaines de préoccupation uniques
La fonctionnalité d'un objet peut être modifiée lors de l'exécution lors de l'utilisation d'un décorateur. Par exemple, dans votre code, vous avez simplement importé le décorateur et l'avez ajouté à votre classe CounterApp
. Maintenant, votre CounterApp
a dynamiquement ajouté des fonctionnalités sans que vous connaissiez les détails de l'implémentation.
// decorator lights is a function which receives the class as an argument
let lights = function(tree) {
// The behaviour of the class is modified here
tree.treeLights = 'Christmas lights'
}
@lights // the decorator is applied here
class ChristmasTree {}
console.log(ChristmasTree.treeLights); // logs Christmas lights