These are called Bitwise operators. . They do operations directly on the bits of the numeric data.
The first two are or and and and work similarly to ||
and &&
but the boolean calculation is done bit by bit of the number. We can roughly say that or does a sum of bits and and does a multiplication. Truth table of these and other operations .
The next two are shift operators or bits offset. The first one is pushing the bits to the right by complementing the space left on the left. The bits that go to the right are discarded. And the second does in the opposite direction. Each bit moved to the left multiplies the number by 2 and in the right shift it is divided by 2.
As can be seen in the MDN linked documentation above there are still the xor (or exclusive) and not operators which is the denial. Remembering that always bit is bit .
All these operations are always done in 32-bit numbers.
A very common use is to accumulate flags as demonstrated below. It is also used in scientific data manipulations, images (mainly colors) and other forms of media, encryption, compression, checksum for data communication, state machines, / p>
In general it is considered low level programming and is often used as a form of optimization, although sometimes there are abuses. x / 2
is equivalent to z >> 1
and x & 1 == 0
is equivalent to x % 2 == 0
It is possible to understand in detail how the calculation is done in the Wikipedia article ( in English ).
var flags = 5; // em binário equivale a 0101
var FLAG_A = 1; // 0001
var FLAG_B = 2; // 0010
var FLAG_C = 4; // 0100
var FLAG_D = 8; // 1000
var mask = FLAG_A | FLAG_B | FLAG_D; // 0001 | 0010 | 1000 => 1011
if (flags & FLAG_C) { // 0101 & 0100 => 0100 => true
// faz alguma coisa
}
if ((flags & FLAG_B) || (flags & FLAG_C)) {
// faz alguma coisa
}
var mask = FLAG_B | FLAG_C; // 0010 | 0100 => 0110
if (flags & mask) { // 0101 & 0110 => 0100 => true
// faz alguma coisa
}
var mask = FLAG_C | FLAG_D; // 0100 | 1000 => 1100
flags |= mask; // 0101 | 1100 => 1101
var mask = ~(FLAG_A | FLAG_C); // ~0101 => 1010
flags &= mask; // 1101 & 1010 => 1000
var mask = ~FLAG_A & ~FLAG_C;
flags &= mask; // 1101 & 1010 => 1000
var mask = FLAG_B | FLAG_C;
flags = flags ^ mask; // 1100 ^ 0110 => 1010
Examples taken from the MDN documentation.