此函数中的JavaScript位运算符的说明

Cal*_*ton 5 javascript bit-manipulation bit bitwise-operators

我有这个代码块:

EventBus.on('pfio.inputs.changed', function(state, prev_state) {
    var changed = prev_state ^ state;
    for (var pin = 0; pin < 8; pin++) {
        if ((changed & (1 << pin)) === (1 << pin)) {
            EventBus.emit('pfio.input.changed', pin, ((state & (1 << pin)) === (1 << pin)));
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

state将是一个8位数:00000000
prev_state将是一个8位数:11001110

这些数字与开关状态有关,因此第一个进入状态意味着引脚1关闭.在prev_state中,前1表示开关8接通.

我理解简单的代码执行,它的这些部分我无法理解:

(changed & (1 << pin)) === (1 << pin))

((state & (1 << pin)) === (1 << pin)));

prev_state ^ state;
Run Code Online (Sandbox Code Playgroud)

对此事的任何解释都会有很大的帮助!

Sea*_*ira 7

^XOR操作员 - 给定两个数字它"排列"他们的位置并且仅当两个数字中只有一个具有该位置时才翻转该位置:

// All of these are binary
111 ^ 111 === 000
110 ^ 111 === 001
110 ^ 110 === 000
Run Code Online (Sandbox Code Playgroud)

这意味着changed将只是一个数字,只有那些设置在prev_state state但不是两者都设置的地方.

至于<<那是左移操作员 - 它有效地将左侧数字提升为右侧数字2的幂:

// Decimal numbers on the left, binary numbers on the right
1 << 1 === 10    // 2
1 << 2 === 100   // 4 
1 << 3 === 1000  // 8

// You can use any number on the LHS
2 << 1 === 100   // 4
3 << 2 === 1100  // 12
// Remember, 3 in decimal is equal to 11 in binary
Run Code Online (Sandbox Code Playgroud)

最后,&是二元和运算符 - 它返回一个数字,只有当两个数字都1在那个地方时才设置地点:

// Both sides binary
1 & 1 === 1
11 & 10 === 10
010 & 100 === 0
Run Code Online (Sandbox Code Playgroud)

因此,在您的循环中,正在检查更改的前8位以查看是否已设置其中任何一项 - 如果其中任何一项已设置,则更改了某些内容并触发了事件.我们可能更容易看出是否将其分解为两个步骤:

// All numbers in binary save for 8 ;-)
prev_state = 11111111;
state = 11011111;
changed = 00100000;
Run Code Online (Sandbox Code Playgroud)

迭代#1:

mask = 1 << 0                   // 0
changeAtPower = changed & mask  // 0
// 0            0         0
mask === changedAtPower         // false
Run Code Online (Sandbox Code Playgroud)

迭代#2:

mask = 1 << 1                   // 10
changeAtPower = changed & mask  // 0
// 00           00        01
mask === changedAtPower         // false
Run Code Online (Sandbox Code Playgroud)

跳过迭代#3到#5,看起来都一样,让我们​​看看#6:

mask = 1 << 5                    // 100000
changedAtPower = changed & mask  // 100000
// 100000        100000    100000
mask === changedAtPower         // true 
// Event triggered
Run Code Online (Sandbox Code Playgroud)

然后它继续进行剩余的迭代(#7和#8),因为没有任何改变,所以不再发生事件.