【问题标题】:How is svelte making a component dirtysvelte 如何使组件变脏
【发布时间】:2020-04-19 19:17:45
【问题描述】:

下面的 sn-p 是我们在 svelte 应用程序上执行 npm run dev 时生成的。

    function make_dirty(component, i) {
        if (component.$$.dirty[0] === -1) {
            dirty_components.push(component);
            schedule_update();
            component.$$.dirty.fill(0);
        }
        component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));
    }

谁能解释一下下面的语句发生了什么?为什么数字 31 是硬编码的?

component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31)); 

谢谢

【问题讨论】:

  • @RobertHarvey 感谢您的提示。但是你能详细说明一下吗?
  • 表达式(i / 31) | 0 相当于一个简单的整数除法。表达式1 &lt;&lt; (i % 31) 在索引i 指定的每个位中产生一个1。例如,i = 0 产生 1 二进制,i = 1 产生 10 二进制,i = 2 产生 100 二进制,等等。

标签: javascript bit-manipulation bit-shift svelte-3


【解决方案1】:

脏数组是一个以整数形式存储多个布尔变量的数组,也称为bit array

默认情况下,JavaScript 中的整数是有符号的 32 位的。它每个整数只存储 31 位而不是 32 位的原因是因为它是有符号的,如果设置了最后一位,则使整数表示negative number。我遗漏了一些上下文,但查看第一个 if 语句,代码似乎为特殊情况保留了负数。

【讨论】:

    【解决方案2】:

    为了扩展 Tijmen 的回答,我将尝试解释这段代码的一些基本原理以及它的实际作用。

    位掩码是一种将多个布尔选项存储在单个整数中的技术。假设您有选项 A、B、C 和 D — 您将值 1、2、4 和 8 分配给它们,然后您可以存储这些选项的任意组合,如下所示:

    • AB — 3
    • BD — 10
    • ACD — 13

    稍后,您可以使用bitwise operators 检索该值:

    if (opts & 1) console.log('A was selected');
    if (opts & 2) console.log('B was selected');
    if (opts & 4) console.log('C was selected');
    if (opts & 8) console.log('D was selected');
    

    Svelte 使用位掩码来跟踪哪些值是,即自上次更新组件以来发生了什么变化。由于 Tijmen 描述的 31 位限制,单个位掩码只能让我们在一个组件中拥有 31 个变量——在大多数情况下很多,但肯定不是全部。所以component.$$.dirty 是一个位掩码数组。

    这行代码……

    component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));
    

    ...弄脏正确位掩码的正确位 — (i / 31) | 0 为我们提供位掩码的索引,(1 &lt;&lt; (i % 31)) 为我们提供该位掩码内的位值,|= 将该位设置为 1 ,无论它之前的值是多少。

    -1 用作sentinel value,表示该组件之前根本没有脏,以便 Svelte 可以将其添加到需要在下一次更新中更新的组件列表中。

    【讨论】:

      猜你喜欢
      • 2023-04-03
      • 2020-07-13
      • 1970-01-01
      • 1970-01-01
      • 2020-07-11
      • 1970-01-01
      • 2019-01-02
      • 1970-01-01
      • 2019-11-21
      相关资源
      最近更新 更多