34

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;
sudo bangbang
  • 27,127
  • 11
  • 75
  • 77
undefined
  • 6,366
  • 12
  • 46
  • 90
  • 1
    It's just variable/property name. `doubled` is probably a typescript interface or a class – adiga Apr 24 '19 at 13:01
  • 5
    `$` is valid character in any JavaScript identifier. Without seeing more context for that code, it looks like a labelled statement to me. – Pointy Apr 24 '19 at 13:02
  • @SudhirOjha you are wrong :) jQuery **is** JavaScript. – Pointy Apr 24 '19 at 13:02
  • @Pointy You can never have enough jQuery. – Malekai Apr 24 '19 at 13:03
  • This is so interesting, i can't find anything about it. – JeuneApprenti Apr 24 '19 at 13:03
  • https://stackoverflow.com/questions/1150381/what-is-the-meaning-of-sign-in-javascript – errorau Apr 24 '19 at 13:03
  • just to add to @Pointy, it's like `label: x = 1 + 1;` – apple apple Apr 24 '19 at 13:04
  • 2
    It works in Chrome console because it's a valid [labeled statement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label). From [their github](https://github.com/sveltejs/svelte/tree/master/src) it looks like they are using typescript. So, it's unlikely that this is labeled statement – adiga Apr 24 '19 at 13:05
  • 1
    It actually works in Vanilla JS! This is ridiculous, I completely expected it to throw a syntax error. – Malekai Apr 24 '19 at 13:06
  • @adiga I understand, possibly incorrectly, that TypeScript is a superset of JavaScript syntax – Pointy Apr 24 '19 at 13:13
  • 1
    @Pointy All javascript is valid typescript** (Conditions apply: `var a = ""; a = 1;` will throw an error). But, it does look like labeled statement after all https://github.com/sveltejs/svelte/blob/4541d587987bb99d91754d24660e59cec5866e44/site/content/tutorial/02-reactivity/02-reactive-declarations/text.md#L14 – adiga Apr 24 '19 at 13:16

5 Answers5

26

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.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • 3
    Not enough jQuery. – Malekai Apr 24 '19 at 13:07
  • @LogicalBranch funny thing is I'm like the last jQuery user on earth I sometimes think. – Pointy Apr 24 '19 at 13:09
  • 1
    I still use various versions of jQuery in production environments, mainly for safety and browser support. It's probably the greatest JS library to exist. – Malekai Apr 24 '19 at 13:13
  • I think the saddest thing about jQuery is when people attack you for using it then make out out to be some kind of demon for wanting good browser support. – Malekai Apr 24 '19 at 13:18
  • 1
    Yea I mean, it just gets rid of a bunch of unnecessary headaches, and so long as it's not abused I don't have a problem with it. (jQueryUI I don't like, however, but that's mostly a matter of design opinion.) – Pointy Apr 24 '19 at 13:19
  • 1
    In the beginning jQuery UI was very promising, then they added those horrific themes/add ons. – Malekai Apr 24 '19 at 13:22
20

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

sudo bangbang
  • 27,127
  • 11
  • 75
  • 77
12

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;
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
4

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

Chris Halcrow
  • 28,994
  • 18
  • 176
  • 206
1

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.

Paul42
  • 194
  • 1
  • 11