web-dev-qa-db-fra.com

Qu'est-ce que c'est: signer après une syntaxe JS variable?

Je suis tombé sur la syntaxe valide suivante dans JS en regardant la bibliothèque svelte:

$: doubled = 6 * 2;

Au début, je pensais que c'était spécifique à la bibliothèque, mais cela fonctionne sur la console Chrome. Quelle est cette syntaxe?

Cela peut être n'importe quoi:

name: something = 6 * 2;
18
undefined

Toute instruction JavaScript (sorte de déclaration de fonction sauf) peut être précédée d'une étiquette:

foo: var x = 0;

Ce que vous avez là est quelque chose comme ça:

$: doubled = 6 * 2;

Dans votre déclaration, "$" est le libellé.

Il n'y a pas grand chose à dire sur les instructions étiquetées car il n'y a pas de goto en JavaScript. break et continue peuvent inclure une étiquette de boucle englobante pour indiquer combien de "couches" doivent être impliquées.

wholeLoop:
for (let i = 0; i < matrix.length; i++) {
  for (let j = 0; j < matrix[i].length; j++) {
    if (matrix[i][j] == null)
      // Oh no! This is terrible
      break wholeLoop;
  }
}

MDN , spec


Tout ce qui précède est à peu près correct, mais apparemment Svelte applique son propre préprocesseur de construction au code source du composant et le traduit en JavaScript réel envoyé au navigateur. Cette utilisation de la syntaxe d'étiquette est "détournée" par eux pour signifier quelque chose; voir la réponse de Quentin.

13
Pointy

En JavaScript, il s'agit d'un label et est conçu pour être utilisé lors de l'utilisation de break et continue en conjonction avec des boucles imbriquées (afin que vous puissiez choisir la boucle que vous cassez ou continue à partir de).

Svelte semble utiliser une sorte de hack pour lui donner un sens alternatif. Voir le tutoriel :

Svelte met automatiquement à jour le DOM lorsque l'état de votre composant change. Souvent, certaines parties de l'état d'un composant doivent être calculées à partir d'autres parties (comme un nom complet dérivé d'un prénom et d'un nom), et recalculées chaque fois qu'elles changent.

Pour ceux-ci, nous avons des déclarations réactives. Ils ressemblent à ceci:

let count = 0;
$: doubled = count * 2;
7
Quentin

Il s'agit d'une étiquette en JavaScript.

Le point intéressant ici est de savoir comment Svelte utilise cela pour lier des variables à d'autres variables. Voici une partie d'une vidéo où Rich Harris explique cela .

Essentiellement, dans Svelte, $: signifie réexécuté chaque fois que ces valeurs changent

Si nous regardons l'exemple dans Svelte's exemple de déclarations réactives ,

<script>
    let count = 1;

    // the `$:` means 're-run whenever these values change'
    $: doubled = count * 2;
    $: quadrupled = doubled * 2;

    function handleClick() {
        count += 1;
    }
</script>

<button on:click={handleClick}>
    Count: {count}
</button>

<p>{count} * 2 = {doubled}</p>
<p>{doubled} * 2 = {quadrupled}</p>

Les variables doubled et quadrupled ont $ label. Ils seront donc à nouveau calculés lorsque count ou doubled changeront respectivement.

Si vous regardez le code compilé, vous pouvez voir

let doubled, quadrupled;
$$self.$$.update = ($$dirty = { count: 1, doubled: 1 }) => {
    if ($$dirty.count) { $$invalidate('doubled', doubled = count * 2); }
    if ($$dirty.doubled) { $$invalidate('quadrupled', quadrupled = doubled * 2); }
};

Ainsi, chaque fois que la mise à jour se produit, il y a une vérification cochonne pour ces variables et la mise à jour.

En conclusion. $: dans Svelte n'a rien à voir avec le libellé JavaScript. C'est une directive pour le compilateur Svelte d'avoir le code pour mettre à jour ces variables. $: est bien sûr une syntaxe valide mais en dehors du contexte de Svelte, il ne fait pas ce qu'il fait dans Svelte. C'est la compilation qui fait la magie;)

6
sudo bangbang