这是什么:在变量 JS 语法之后签名?

What is this : sign after a variable JS syntax?

我在查看 svelte 库时在 JS 中遇到了以下有效语法:

$: doubled = 6 * 2;

起初,我以为它是特定于库的,但它适用于 Chrome 控制台。这是什么语法?

可以是任何东西:

name: something = 6 * 2;

任何 JavaScript 语句(函数声明除外)都可以在标签之前:

foo: var x = 0;

你得到的是这样的东西:

$: doubled = 6 * 2;

在您的声明中,“$”是标签。

标签语句没有多大意义,因为 JavaScript 中没有 gotobreakcontinue 都可以包含一个封闭循环的标签,以指示应该涉及多少 "layers"。

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


以上所有内容几乎都是正确的,但显然 Svelte 将自己的构建时预处理器应用于组件源代码,并将其转换为发送给浏览器的实际 JavaScript。他们对标签语法的这种使用 "hijacked" 表示某种含义;参见昆汀的回答。

在 JavaScript 中,它是一个 label 并且设计用于在 breakcontinue 与嵌套循环结合使用时使用(因此您可以选择您正在中断或继续的循环)。

Svelte 似乎使用了某种技巧来赋予它另一种含义。见 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;

这是 JavaScript 中的标签。

这里有趣的一点是 Svelte 如何使用它来将变量绑定到其他变量。 Here's a portion of a video where Rich Harris explains this.

本质上,在 Svelte 中,$: 意味着只要这些值发生变化 re-运行

如果我们看一下 Svelte 中的示例 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>

变量 doubledquadrupled$ 标签。因此,当 countdoubled 分别发生变化时,它们将再次计算。

如果你看一下编译后的代码,你可以看到

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

因此,每次更新发生时,都会对这些变量进行脏检查并进行更新。

总之。 Svelte 中的 $: 与 JavaScript 标签没有任何关系。这是 Svelte 编译器的指令,用于更新这些变量的代码。 $: 当然是有效的语法,但在 Svelte 的上下文之外,它不会做它在 Svelte 中所做的事情。这是神奇的汇编 ;)

要为已提供的答案添加更多详细信息:

  • 它在 Svelte 中本质上定义了一个'destiny operator'(命运运算符是 'reactive programming' 的一般概念)
  • 命运运算符确保在计算变量的值发生变化时更新变量)

Rich Harris(Svelte 的创建者)不久前写了一篇关于使用命运运算符的文章,很好地解释了这个概念(尽管当时他没有特别建议使用 $

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

对于 Svelte.js 具体而言,$: Marks A Statement as 'reactive' 意味着它将根据后面的变量进行更新 - 正如其他人也写的那样,这是 javascript 中的标签, 但在 svelte 中它有特殊的含义。