undefined
undefined

Reputation: 6844

What is this : sign after a variable JS syntax?

I came across the following valid syntax in JS when looking at svelte library:

$: doubled = 6 * 2;

At first, I thought it was specific for the library, but it works on the Chrome console. What is this syntax?

It can be anything:

name: something = 6 * 2;

Upvotes: 35

Views: 5096

Answers (5)

Paul42
Paul42

Reputation: 304

For Svelte.js specifically, that $: Marks A Statement as 'reactive' meaning that it will update based on the variables that follow - as others have also written that's a label in javascript, but in svelte it has special meaning.

Upvotes: 1

Chris Halcrow
Chris Halcrow

Reputation: 31950

To add more detail to the answers already provided:

  • It essentially defines a 'destiny operator' in Svelte (a destiny operator is a general concept of 'reactive programming')
  • A destiny operator ensures a variable is updated whenever values that it's computed from are changed)

Rich Harris (the creator of Svelte) wrote an article a while back about use of the destiny operator, that explains the concept well (although at the time he didn't specifically suggest using $:

https://gist.github.com/Rich-Harris/aa3dc83d3d8a4e572d9be11aedc8c238

Upvotes: 4

sudo bangbang
sudo bangbang

Reputation: 28179

This is label in JavaScript.

The interesting point here is how Svelte is using this to bind variables to other variables. Here's a portion of a video where Rich Harris explains this.

Essentially, in Svelte, $: means re-run whenever these values change

If we look a the example in Svelte's Reactive declarations example,

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

The variables doubled and quadrupled have $ label. So, they'll be computed again when count or doubled changes respectively.

If you take a look at the compiled code, you can see

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); }
};

So, each time the update happens, there is a dirty check for those variables and update.

In conclusion. $: in Svelte doesn't have anything to do with JavaScript label. It's a directive for Svelte compiler to have the code for updating those variables. $: is of course valid syntax but outside the context of Svelte, it doesn't do what it does in Svelte. It's the compilation that does the magic ;)

Upvotes: 21

Pointy
Pointy

Reputation: 413712

Any JavaScript statement (kind-of except function declarations) can be preceded by a label:

foo: var x = 0;

What you've got there is something like that:

$: doubled = 6 * 2;

In your statement, "$" is the label.

There's not much point to labelled statements because there's no goto in JavaScript. Both break and continue can include a label of an enclosing loop to indicate how many "layers" should be involved.

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


All the above is pretty much correct, but apparently Svelte applies its own build-time preprocessor to component source code and translates that into the actual JavaScript sent to the browser. This use of the label syntax is "hijacked" by them to mean something; see Quentin's answer.

Upvotes: 26

Quentin
Quentin

Reputation: 943214

In JavaScript, it is a label and is designed to be used when using break and continue in conjunction with nested loops (so you can pick which loop you are breaking or continuing from).

Svelte appears to use some kind of hack to give it alternative meaning. See the tutorial:

Svelte automatically updates the DOM when your component's state changes. Often, some parts of a component's state need to be computed from other parts (such as a fullname derived from a firstname and a lastname), and recomputed whenever they change.

For these, we have reactive declarations. They look like this:

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

Upvotes: 12

Related Questions