Что означает один вертикальный бар в JavaScript?

Что означает это выражение в JS?

Value |= this.value

Ответ 1

Он двоичный "ИЛИ", как на C, С++ или Java. В этом случае он используется в форме оператора присваивания, поэтому

value |= this.value

означает, что this.value и value оба преобразуются в 32-битные целые числа, и выполняется побитовая операция ИЛИ. Если value было 10 и this.value составляли 3 перед операцией (т.е. 01010 и 011 в двоичном выражении), результат был бы равен 11 (01011 в двоичном выражении).

Операторы двоичной логики в Javascript заметны в Javascript, потому что работа выполняется по целочисленным значениям.

Термин "бит-мудрый", возможно, более точен, чем "двоичный". Операции действуют на каждый бит числового значения, в частности числовые значения, принудительные к подписанным 32-битным целым числам. Результатом является также подписанное 32-битное целое число (согласно спецификации).

Однако номера JavaScript "в состоянии покоя" всегда являются 64-битными двоичными значениями с плавающей запятой. Таким образом, результаты побитовых операторов, хотя и рассчитанные с 32-битной целочисленной математикой, сохраняются в форме с плавающей запятой. Это работает, потому что диапазон 32-битных целых чисел удобно и точно подходит для 64-битного поплавка.

Ответ 2

Это будет выполнять побитовое ИЛИ между битами в this.value и битами, уже сохраненными в Value, а затем сохранить результат обратно в Value.

var Value = 42;  // 00101010
Value |= 96;     // 01100000
window.alert(Value);  // 01101010 -> 106

Ответ 3

Как указывали другие, это побитовый оператор OR. Тем не менее, я не думаю, что люди много используют его в числовых значениях в Javascript как обычно - вы не делаете много вычислений в Javascript. Чтобы дать вам более полное представление о том, почему этот оператор полезен, рассмотрите гораздо более распространенный сценарий, который пользователь должен заполнить, по крайней мере, одним из нескольких текстовых полей.

Скажем, у вас есть этот HTML-код:

<input type="text" class="phone-nr" id="home-phone-nr-1" />
<input type="text" class="phone-nr" id="home-phone-nr-2" />
<input type="text" class="phone-nr" id="home-phone-nr-3" />
<input type="text" class="phone-nr" id="mobile-phone-nr-1" />
<input type="text" class="phone-nr" id="mobile-phone-nr-2" />
<input type="text" class="phone-nr" id="mobile-phone-nr-3" />

Пользователь имеет возможность заполнить несколько телефонных номеров, но должен будет предоставить хотя бы один.

Самый простой способ сделать это (с jQuery в этом случае):

var valid = false;
$('.phone-nr').each(function(i, item){
  valid |= $(item).val();
}); // untested code

valid будет истинным, если хотя бы одно поле ввода с классом phone-nr имеет непустое значение.

Если каждое поле должно быть заполнено (более общее требование), вы можете сделать это следующим образом с побитовым оператором AND:

var valid = true;
$('.phone-nr').each(function(i, item){
  valid &= $(item).val();
}); // untested code

valid будет истинным только в том случае, если поля ввода все имеют значение.

Если для заполнения требуется хотя бы одно поле, но не более одного, вы можете использовать оператор XOR:

var valid = false;
$('.phone-nr').each(function(i, item){
  valid ^= $(item).val();
}); // untested code

Это, на мой взгляд, реальное использование побитовых операторов в Javascript.

Ответ 4

Некоторое практическое применение для этого оператора я нашел:

( 3|0 ) === 3;             // целые числа не изменяет
( 3.3|0 ) === 3;           // у дробных чисел отбрасывает дробную часть
( 3.8|0 ) === 3;           // не округляет, а именно отбрасывает дробную часть
( -3.3|0 ) === -3;         // в том числе и у отрицательных дробных чисел
( -3.8|0 ) === -3;         // у которых Math.floor(-3.3) == Math.floor(-3.8) == -4
( "3"|0 ) === 3;           // строки с числами преобразуются к целым числам
( "3.8"|0 ) === 3;         // при этом опять же отбрасывается дробная часть
( "-3.8"|0 ) === -3;       // в том числе и у отрицательных дробных чисел
( NaN|0 ) === 0;           // NaN приводится к нулю
( Infinity|0 ) === 0;      // приведение к нулю происходит и с бесконечностью,
( -Infinity|0 ) === 0;     // и с минус бесконечностью,
( null|0 ) === 0;          // и с null,
( (void 0)|0 ) === 0;      // и с undefined,
( []|0 ) === 0;            // и с пустым массивом,
( [3]|0 ) === 3;           // но массив с одним числом приводится к числу,
( [-3.8]|0 ) === -3;       // в том числе с отбрасыванием дробной части,
( [" -3.8 "]|0 ) === -3;   // и в том числе с извлечением чисел из строк,
( [-3.8, 22]|0 ) === 0     // но массив с несколькими числами вновь зануляется
( {}|0 ) === 0;                // к нулю также приводится пустой объект
( {'2':'3'}|0 ) === 0;         // или не пустой
( (function(){})|0 ) === 0;    // к нулю также приводится пустая функция
( (function(){ return 3;})|0 ) === 0;

и какая-то магия для меня:

3 | '0px' === 3;

Ответ 5

Это побитовый или присваивающий оператор, похожий на +=. Если вы выполните тест на нем следующим образом:

<ol>
<script language="javascript">
var x=false;
document.writeln("<li>"+x+"</li>");
x|=true;
document.writeln("<li>"+x+"</li>");
x&=false;
document.writeln("<li>"+x+"</li>");
</script>
</ol>

Вы получите этот вывод (в IE)

1.false
2.1
3.0

По существу, x|=y совпадает с x=x|y