Что делает оператор | = делать в JavaScript?

Я нашел следующий код в проекте JS:

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

Что делает |= в теле цикла for?

Пример кода сомнительный, но был представлен здесь на V8 для примера повышения производительности.

Обновленный пример

Приведенный выше пример эквивалентен var a = [15]; для большинства целей и целей. Более реалистичным примером для оператора |= было бы создание двоичных флагов в одной переменной, например, на объекте разрешения:

//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
}

Ответ 1

a[0] |= b

в основном

a[0] = a[0] | b

"|" является или побитовым оператором (кстати: документы MDN действительно хорошо написаны и действительно понятны. Если OP хочет писать и понимать JS, то документы MDN - отличный ресурс.)

Обновление Когда a[0] назначается 0, a[0] в двоичном формате 0000. В цикле

  • 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)
    
  • 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)
    
  • 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)
    
  • 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)
    
  • 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)
    
  • 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)
    
  • 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)
    
  • 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)
    
  • 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)
    
  • 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)
    

В конце цикла значение a[0] равно 15

Ответ 2

x |= y;

эквивалентно

x = x | y;

где | означает побитовое ИЛИ.

Ответ 3

Он работает примерно так: если b больше, чем a, b добавляется b.

В действительности происходит a = a | b, как и для других операторов. Это означает a = a BITWISE OR b, который объясняется здесь.

Например, это результат нескольких операций:

var a = 1;
a |= 2; // a = 3
a |= 2; // a = 3
a |= 4; // a = 7

Я надеюсь, что это поможет.

Ответ 4

Как и в случае с большинством операторов присваивания, это эквивалентно повторению оператора, использующего значение lefthand:

a |= b
a = a | b

Как и

a += b
a = a + b

Посмотрите Moz Dev Net для более подробной информации.

[Изменить: Мозг не работает, перепутано | и ||. Вам нужно больше кофе. Изменено ниже]

Так как | - это побитовый оператор OR, результатом a|b будет целое число, представляющее битовую строку со всеми 1 битами a и b. Обратите внимание, что javascript не имеет собственных типов int или bitstring, поэтому сначала он будет передавать a и b в int, а затем побитовое ИЛИ на битах. Итак, 9 | 2 в двоичном формате - 1001 | 0010 = 1011, что равно 11, но 8 | 2 = 8.

Эффект состоит в том, чтобы добавить бит флага b в a. Поэтому, если у вас есть флаг WEEVILFLAG=parseInt(00001000,2):

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

установит этот бит в 1 в a.

Ответ 5

Возвращает одну в каждой позиции бита, для которой соответствующие биты одного или обоих операндов являются единицами.

код:   result = a | б;

^ - побитовый оператор XOR, который возвращает один для каждой позиции, где один (не оба) из соответствующих битов его операндов один. Следующий пример возвращает 4 (0100):