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

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

Value |= this.value

5 ответов

Решение

Это двоичное "ИЛИ", как в C или 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-разрядное число с плавающей точкой.

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

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

Как уже отмечали другие, это побитовый оператор ИЛИ. Тем не менее, я не думаю, что люди часто используют его для числовых значений в 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.

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

( 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;

Это побитовый оператор или оператор присваивания, похожий на +=, Если вы запустите тест на нем, как это:

<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

Другие вопросы по тегам