【问题标题】:What is this : sign after a variable JS syntax?这是什么:变量JS语法后的符号?
【发布时间】:2019-09-13 18:51:02
【问题描述】:

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

$: doubled = 6 * 2;

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

可以是任何东西:

name: something = 6 * 2;

【问题讨论】:

  • 只是变量/属性名。 doubled 可能是 typescript 接口或类
  • $ 是任何 JavaScript 标识符中的有效字符。在没有看到该代码的更多上下文的情况下,它在我看来就像一个带标签的语句。
  • 它可以在 Chrome 控制台中使用,因为它是一个有效的labeled statement。从their github 看来他们正在使用打字稿。所以,这不太可能是标签声明
  • 它实际上可以在 Vanilla JS 中使用!这太荒谬了,我完全期望它会抛出语法错误。
  • @Pointy 所有 javascript 都是有效的打字稿**(适用条件:var a = ""; a = 1; 将引发错误)。但是,毕竟github.com/sveltejs/svelte/blob/… 看起来确实像带标签的声明

标签: javascript syntax svelte


【解决方案1】:

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

foo: var x = 0;

你得到的东西是这样的:

$: doubled = 6 * 2;

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

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

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。标签语法的这种使用被他们“劫持”为某种含义。见昆汀的回答。

【讨论】:

  • 没有足够的 jQuery。
  • @LogicalBranch 有趣的是,我有时会认为我就像地球上最后一个 jQuery 用户。
  • 我在生产环境中仍然使用各种版本的jQuery,主要是为了安全和浏览器支持。它可能是现存最伟大的 JS 库。
  • 是的,我的意思是,它只是摆脱了一堆不必要的头痛,只要它没有被滥用,我就没有问题。 (不过,我不喜欢 jQueryUI,但这主要是设计意见的问题。)
  • 一开始 jQuery UI 很有前途,后来他们添加了那些可怕的主题/插件。
【解决方案2】:

这是 JavaScript 中的标签。

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

基本上,在 Svelte 中,$: 意味着只要这些值发生变化就重新运行

如果我们看一下 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 中那样做。神奇的是编译 ;)

【讨论】:

    【解决方案3】:

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

    Svelte 似乎使用了某种技巧来赋予它另一种含义。见the tutorial:

    Svelte 会在组件状态时自动更新 DOM 变化。通常,需要计算组件状态的某些部分 来自其他部分(例如从名字派生的全名和 lastname),并在更改时重新计算。

    对于这些,我们有反应式声明。它们看起来像这样:

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

    【讨论】:

    • 我一定是做错了什么,我只是报错了这个错误“Uncaught ReferenceError: assignment to undeclared variable doubled”
    【解决方案4】:

    为已经提供的答案添加更多细节:

    • 它本质上在 Svelte 中定义了一个“destiny operator”(命运运算符是“反应式编程”的一般概念)
    • 命运运算符确保在计算变量的值发生变化时更新变量)

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

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

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        猜你喜欢
        • 2016-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-21
        • 1970-01-01
        • 2010-11-23
        • 2019-09-16
        相关资源
        最近更新 更多