50

I found the following code in a JS project:

var a = new Array();
a[0] = 0;
for (var b = 0; b < 10; b++) {
  a[0] |= b; 
}

What does the |= do in the body of the for loop?

The code example is dubious, but has been presented here by V8 for an example of improved performance.

Updated Example

The above example is equivalent to var a = [15]; for most intents and purposes. A more realistic example for the |= operator would be to set up binary flags in a single variable, for example on a permission object:

//Set up permission masks
var PERMISSION_1_MASK = parseInt('0001',2);
var PERMISSION_2_MASK = parseInt('0010',2);
..

//Set up permissions
userPermissions = 0;
userPermissions |= hasPermissionOne && PERMISSION_1_MASK;
userPermissions |= hasPermissionTwo && PERMISSION_2_MASK;
..

//Use permissions
if(userPermissions & PERMISSION_1_MASK){
    ..//Do stuff only allowed by permission 1
}
Briguy37
  • 7,992
  • 2
  • 29
  • 49
ContentiousMaximus
  • 1,214
  • 2
  • 14
  • 24

4 Answers4

97
a[0] |= b

is basically

a[0] = a[0] | b

"|" is an or bitwise operator

Update When a[0] is assigned 0, a[0] in binary is 0000. In the loop,

  1. b = 0

    a[0] = 0 (base 10) = 0000 (base 2)
    b    = 0 (base 10) = 0000 (base 2)
                       ---------------
    a[0] | b           = 0000 (base 2) = 0 (base 10)
    
  2. b = 1

    a[0] = 0 (base 10) = 0000 (base 2)
    b    = 1 (base 10) = 0001 (base 2)
                       ---------------
    a[0] | b           = 0001 (base 2) = 1 (base 10)
    
  3. b = 2

    a[0] = 1 (base 10) = 0001 (base 2)
    b    = 2 (base 10) = 0010 (base 2)
                       ---------------
    a[0] | b           = 0011 (base 2) = 3 (base 10)
    
  4. b = 3

    a[0] = 3 (base 10) = 0011 (base 2)
    b    = 3 (base 10) = 0011 (base 2)
                       ---------------
    a[0] | b           = 0011 (base 2) = 3 (base 10)
    
  5. b = 4

    a[0] = 3 (base 10) = 0011 (base 2)
    b    = 4 (base 10) = 0100 (base 2)
                       ---------------
    a[0] | b           = 0111 (base 2) = 7 (base 10)
    
  6. b = 5

    a[0] = 7 (base 10) = 0111 (base 2)
    b    = 5 (base 10) = 0101 (base 2)
                       ---------------
    a[0] | b           = 0111 (base 2) = 7 (base 10)
    
  7. b = 6

    a[0] = 7 (base 10) = 0111 (base 2)
    b    = 6 (base 10) = 0110 (base 2)
                       ---------------
    a[0] | b           = 0111 (base 2) = 7 (base 10)
    
  8. b = 7

    a[0] = 7 (base 10) = 0111 (base 2)
    b    = 7 (base 10) = 0111 (base 2)
                       ---------------
    a[0] | b           = 0111 (base 2) = 7 (base 10)
    
  9. b = 8

    a[0] = 7 (base 10) = 0111 (base 2)
    b    = 8 (base 10) = 1000 (base 2)
                       ---------------
    a[0] | b           = 1111 (base 2) = 15 (base 10)
    
  10. b = 9

    a[0] = 15 (base 10) = 1111 (base 2)
    b    =  9 (base 10) = 1001 (base 2)
                        ---------------
    a[0] | b            = 1111 (base 2) = 15 (base 10)
    

At the end of the loop the value of a[0] is 15

John R Perry
  • 3,357
  • 1
  • 30
  • 46
Jacob George
  • 2,393
  • 1
  • 14
  • 28
51
x |= y;

is equivalent to

x = x | y;

where | stands for bitwise OR.

freakish
  • 48,318
  • 8
  • 114
  • 154
  • Is there an idiomatic meaning? Or some trick, like when you floor down floats with `~~`? – katspaugh Oct 12 '12 at 08:59
  • 1
    @katspaugh There is. For example it can be used for efficient encoding and checking for privileges ( this would fit with OP code as well ). Read [this article](http://www.php4every1.com/tutorials/create-permissions-using-bitwise-operators-in-php/). – freakish Oct 12 '12 at 09:11
  • 1
    @katspaugh what did u mean by "floor down floats with ~~"? I have never heard of such a thing! – Jacob George Oct 12 '12 at 11:16
8

As with most assignment operators, it is equivalent to applying the operator using the lefthand value again:

a |= b
a = a | b

Just like

a += b
a = a + b

Look on Moz Dev Net for more.

[Edit: Brain fail, mixed up | and ||. Need more coffee. Modified below]

Since | is the Bitwise OR operator, the result of a|b will be the integer representing the bitstring with all the 1 bits of a and b. Note that javascript has no native int or bitstring types, so it will first cast a and b to int, then do a bitwise OR on the bits. So 9 | 2 in binary is 1001 | 0010 = 1011, which is 11, but 8|2 = 8.

The effect is to add the flag bits of b into a. So if you have some flag WEEVILFLAG=parseInt(00001000,2) :

// a = parseInt(01100001,2)
if(isWeevilish(a))
    a |= WEEVILFLAG;
// now a = parseInt(01101001,2)

will set that bit to 1 in a.

Phil H
  • 18,593
  • 6
  • 62
  • 99
5

Returns a one in each bit position for which the corresponding bits of either or both operands are ones.

Code: result = a | b;

^ is the bitwise XOR operator, which returns a one for each position where one (not both) of the corresponding bits of its operands is a one. The next example returns 4 (0100):

Ultimater
  • 4,309
  • 2
  • 26
  • 40
sourabh kasliwal
  • 938
  • 2
  • 8
  • 21