苗条如何使组件变脏

Sid*_*Pal 3 javascript bit-manipulation bit-shift svelte-3

下面的代码片段是我们npm run devsvelte应用程序上执行时生成的内容。

    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));
    }
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释下面的声明发生了什么吗?为什么数字 31 是硬编码的?

component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31)); 
Run Code Online (Sandbox Code Playgroud)

谢谢

Ric*_*ris 5

为了稍微扩展 Tijmen 的答案,我将尝试解释这段代码的一些基本原理以及它实际在做什么。

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

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

稍后,您可以使用按位运算符检索值:

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');
Run Code Online (Sandbox Code Playgroud)

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

这行代码...

component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));
Run Code Online (Sandbox Code Playgroud)

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

-1 用作标记值,用于指示组件之前根本没有脏,以便 Svelte 可以将其添加到需要在下一个滴答声中更新的组件列表中。