admin管理员组

文章数量:1405747

The snippet below is what gets generated when we do a npm run dev on svelte app.

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

Can anybody please explain what is happening with the statement below? Why is the number 31 hard-coded?

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

Thanks

The snippet below is what gets generated when we do a npm run dev on svelte app.

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

Can anybody please explain what is happening with the statement below? Why is the number 31 hard-coded?

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

Thanks

Share edited Jan 1, 2020 at 9:16 Siddharth Pal asked Dec 31, 2019 at 7:39 Siddharth PalSiddharth Pal 1,45811 silver badges24 bronze badges 2
  • @RobertHarvey Thanks for the hint. But can you please elaborate more? – Siddharth Pal Commented Dec 31, 2019 at 16:32
  • 2 The expression (i / 31) | 0 amounts to a simple integer division. The expression 1 << (i % 31) yields a 1 in each bit place designated by index i. For example, i = 0 yields 1 binary, i = 1 yields 10 binary, i = 2 yields 100 binary, and so on. – Robert Harvey Commented Dec 31, 2019 at 16:43
Add a ment  | 

2 Answers 2

Reset to default 9

To expand a bit on Tijmen's answer, I'll try and explain some of the rationale for this code as well as what it's actually doing.

A bitmask is a technique for storing multiple boolean options in a single integer. Say you have options A, B, C and D — you assign the values 1, 2, 4 and 8 to them, and then you can store any bination of those options like so:

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

Later, you can retrieve the value using 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 uses bitmasks to track which values are dirty, i.e. what has changed since the ponent was last updated. Because of the 31 bit limit Tijmen described, a single bitmask would only let us have 31 variables in a ponent — plenty in most circumstances, but certainly not all. So ponent.$$.dirty is an array of bitmasks.

This line of code...

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

...dirties the correct bit of the correct bitmask — the (i / 31) | 0 gives us the index of the bitmask, (1 << (i % 31)) gives us the value of the bit within that bitmask, and |= sets the bit to 1, whatever its value was before.

The -1 is used as a sentinel value for indicating that the ponent wasn't previously dirty at all, so that Svelte can add it to the list of ponents that need to be updated in the next tick.

The dirty array is an array that stores multiple Boolean variables in an integer, also know as a bit array.

Integers in JavaScript are, by default, signed and 32-bit. The reason it only stores 31 bits per integer instead of 32 that because it's signed, the last bit, if set, makes the integer represent a negative number. I'm missing some context, but looking at the first if-statement, the code seems to reserve negative numbers for special cases.

本文标签: javascriptHow is svelte making a component dirtyStack Overflow