Зачем использовать логические операторы, когда побитовые операторы делают то же самое?

считайте это условие:

(true & true & false & false & true) == true //returns: false

Как вы можете видеть, побитовое и поведение точно такое же, как логическое и:

(true && true && false && false && true) == true //returns: false

мне интересно почему Я должен использовать логические операции, когда побитовые операции делают то же самое, что и логические.

Примечание: пожалуйста, не отвечайте, что это из-за проблемы с производительностью, потому что это намного быстрее в Mozilla Firefox, см. Этот jsPerf: http://jsperf.com/bitwise-logical-and

10 ответов


наиболее распространенным использованием оценок короткого замыкания с использованием логических операторов является не производительность, но избежать ошибок. Смотри:

if (a && a.length)

вы не можете просто использовать & здесь.

обратите внимание, что с помощью & вместо && не может быть сделано, когда вы не справляетесь с логическими значениями. Например & on 2 (01 в двоичном формате) и 4 (10 в двоичном формате) является 0.

обратите внимание также, что, кроме в if тесты && (так же, как ||) также используется, потому что он возвращает один из операндов :

"a" & "b" => 0
"a" && "b" => "b"

в более общем смысле, используя & на месте && часто можно. Как обходить ; в вашем коде javascript. Но это заставит вас думать больше, чем необходимо (или принесет вам странные ошибки время от времени).


побитовое поведение операций то же самое?

нет, это не так. Побитовые операторы работают с целыми числами,а логические операторы имеют разную семантику. Только при использовании чистых логических значений результат может быть похожим.

вы уже можете видеть эту разницу в типе результата:

(true & true & false & false & true) === 0
(true && true && false && false && true) === false

нет, они не делают то же самое. Различия:

  1. преобразуются ли типы операндов
  2. оцениваются ли оба операнда
  3. возвращаемое значение
// sample functions 
function a() { console.log("a()"); return false; }
function b() { console.log("b()"); return true; }

&& (логическое и)

  1. проверяет правдивость операндов
  2. использует короткое замыкание и не может оценить второй операнд
  3. возвращает последний операнд вычисляется без типа преобразование
a() && b();
// LOG: "a()"
// RET: false

& (побитовое и)

  1. временно преобразует операнды в их 32-битное целочисленное представление (при необходимости)
  2. вычисляет оба операнда
  3. возвращает число
a() & b();
// LOG: "a()"
// LOG: "b()"
// RET: 0

потому что с помощью && или & передают разные намерения.

первый говорит, что вы тестируете truthiness.

второй означает, что вы вызываете немного магии. В реальном коде, вы будете смотреть на variable1 & variable2. Это будет не будьте ясны, что вы на самом деле намереваетесь проверить истину (не truthiness). Читатель кода, вероятно, будет смущен, потому что не ясно, почему .

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


почти все уже сказал, но просто для полноты, я хочу взглянуть на аспект исполнения:

JavaScript имеет много трудных для запоминания правил о том, как оценивать выражения. Это включает в себя много литья, когда дело доходит до более сложных сравнений. Массивы и объекты необходимо преобразовать, вызвав их toString() методы и затем приводятся к числам. Это огромный производительность.

рассмотрим следующие короткие пример схемы, когда задействованы массив и объект:

( false  & {}  & [] ) == true
( false && {} && [] ) == true

производительность имеет значение


  1. Boolean позволяет короткое замыкание, которое может быть повышением производительности или проверкой безопасности.
  2. нелогические значения, используемые в условном. Например, if ( 1 & 2 ) вернет false, тогда как if ( 1 && 2 ) вернет true.

вы не можете битовые операторы короткого замыкания. Кроме того, побитовые операторы могут делать гораздо больше, а не просто вычислять логическое выражение.


существует огромная разница: логические операции закорочены. Это означает ,что (true && true && false) - последнее, что нужно выполнить. Это позволяет создавать мощные конструкции, такие как абстрактная заводская модель с использованием var myFunc = mozilla.func || opera.sameFunc || webkit.evenOneMoreVariationOfTheSameConcept;

все подвыражения побитовых операций должны быть полностью оценены -- и btw. в любом случае редко нужно оценивать постоянные побитовые или логические выражения.


первое условие должно сначала преобразовать и суммировать биты. Но второй проверит логическое и возвращаемое значение.

таким образом, первый будет медленнее, чем второй.

Запустите Этот Тест:http://jsperf.com/bitwise-logical

на Chrome & IE побитовое медленнее но на FireFox логика медленнее


var bit1 = (((true & true) & (false & false)) & true), // return 0;
    bit2 = (((true && true) && (false && false)) && true); // return flase

alert(bit1 + ' is not ' + bit2);