svelte 如何使组件变脏

How is svelte making a component dirty

下面的代码片段是我们在 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)); 

谢谢

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

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

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

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

  • AB — 3
  • 蓝天 — 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 << (i % 31)) 给了我们该位掩码中位的值,|= 将该位设置为 1,无论其之前的值是什么。

-1 用作 sentinel value 表示该组件之前根本不是脏的,因此 Svelte 可以将其添加到下一个 tick 中需要更新的组件列表.