Po co używać operatorów logicznych, skoro operatory bitowe robią to samo?

Rozważmy ten warunek:

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

Jak widać, bitowe i zachowanie jest dokładnie takie jak logiczne i:

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

Zastanawiam się Dlaczego powinienem używać operacji logicznych, gdy operacje bitowe robią to samo, co operacje logiczne.

Uwaga: proszę nie odpowiadać to z powodu problemów z wydajnością, ponieważ w Mozilli Firefox jest to znacznie szybsze, zobacz ten jsPerf: http://jsperf.com/bitwise-logical-and

Author: Salman A, 2013-02-14

10 answers

Najczęstszym zastosowaniem ocen zwarciowych przy użyciu operatorów logicznych nie jest wydajność, ale unikanie błędów. ZOBACZ TO:

if (a && a.length)

Nie możesz po prostu użyć & tutaj.

Zauważ, że użycie & zamiast && nie może być zrobione, jeśli nie masz do czynienia z booleanami. Na przykład & on 2 (01 w formacie binarnym) oraz 4 (10 w binarnym) jest 0.

Zauważ również, że oprócz testów if, && (podobnie jak ||) jest również używany, ponieważ zwraca jeden z operands :

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

Bardziej ogólnie, użycie & zamiast && jest często możliwe. Tak jak pominięcie większości ; w Twoim kodzie javascript. Ale to zmusi cię do myślenia więcej niż to konieczne (lub przyniesie Ci dziwne błędy od czasu do czasu).

 20
Author: Denys Séguret,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-14 10:55:23

Operacje bitowe zachowują się tak samo?

Nie, Nie jest. Operatory bitowe pracują na liczbach całkowitych, podczas gdy operatory logiczne mają stronlgy różne semantyki. Tylko przy użyciu czystych wartości logicznych wynik może być podobny.
  • operatory bitowe: Evalutate both operands, convert to 32-bit integer, operate on them, and return the number.
  • operatory logiczne : Oceń pierwszy operand, jeśli jest prawdziwy / fałszywy, to evalutate i zwróć drugi operand else zwróć pierwszy wynik. To się nazywa ocena zwarcia

Już widzisz tę różnicę w rodzaju wyniku:

(true & true & false & false & true) === 0
(true && true && false && false && true) === false
 11
Author: Bergi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-14 09:22:49

Nie robią tego samego. Różnice są następujące:

  1. Czy typy operandów są konwertowane
  2. czy oba operandy są oceniane
  3. wartość zwracana
// sample functions 
function a() { console.log("a()"); return false; }
function b() { console.log("b()"); return true; }

&& (logiczne i)

  1. sprawdza prawdziwość operandów
  2. używa zwarcia i nie może oceniać drugiego operanda
  3. zwraca ostatni oceniany operand bez konwersji typu
a() && b();
// LOG: "a()"
// RET: false

& (bitowe i)

  1. tymczasowo konwertuje operandy na ich 32-bitową reprezentację całkowitą (jeśli to konieczne)
  2. ocenia oba operandy
  3. Zwraca liczbę
a() & b();
// LOG: "a()"
// LOG: "b()"
// RET: 0
 8
Author: Salman A,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-14 12:02:57

Ponieważ użycie && LUB & przekazuje różne intencje.

Pierwszy mówi, że testujesz truthness.

Drugi oznacza wyczarowanie odrobiny magii. W prawdziwym kodzie będziesz patrzył na variable1 & variable2. To będzie nie jasne, że w rzeczywistości zamierzacie sprawdzić prawdę (nie truthness). Czytelnik kodu prawdopodobnie będzie zdezorientowany, ponieważ nie jest oczywiste, dlaczego & został użyty.

Ponadto semantyka to całkowicie różni się, biorąc pod uwagę inne wartości niż Boole i wywołania funkcji, o czym świadczą liczne inne posty.

 3
Author: phant0m,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-14 09:25:41

Prawie wszystko jest już powiedziane, ale dla kompletności chcę rzucić okiem na aspekt wydajności:

JavaScript ma wiele trudnych do zapamiętania reguł oceniania wyrażeń. Obejmuje to wiele odlewów, jeśli chodzi o bardziej złożone porównania. Tablice i Obiekty muszą zostać przekonwertowane przez wywołanie ich metod toString(), a następnie zamienione na liczby. To jest ogromny hit wydajności.

Rozważ następujący przykład zwarcia, gdy array i obiekt są zaangażowane:

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

Wydajność ma znaczenie

 2
Author: Christoph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-14 09:54:11
  1. Boolean umożliwia zwarcie, które może być zwiększeniem wydajności lub kontrolą bezpieczeństwa.
  2. nie-logiczne wartości używane w warunkowym. Na przykład, if ( 1 & 2 ) zwróci false, podczas gdy if ( 1 && 2 ) zwróci true.
 2
Author: David Kiger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-14 13:01:57

Nie można zwarciowych operatorów bitowych. Również operatory bitowe mogą zrobić znacznie więcej, nie tylko obliczyć wyrażenie logiczne.

 1
Author: Ivaylo Strandjev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-14 09:03:14

Jest ogromna różnica: operacje logiczne są zwarte. Oznacza to, że (true && true && false ) jest ostatnią rzeczą do wykonania. Pozwala to na potężne konstrukcje, takie jak abstrakcyjny model fabryczny przy użyciu var myFunc = mozilla.func || opera.sameFunc || webkit.evenOneMoreVariationOfTheSameConcept;

Wszystkie podwyrażenia operacji bitowych muszą być w pełni ocenione -- i btw. rzadko trzeba i tak Oceniać stałe wyrażenia bitowe lub logiczne.

 1
Author: Aki Suihkonen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-14 09:04:31

Pierwszy warunek musi skonwertować pierwsze i sumować bity. Ale drugi sprawdzi wartość logiczną i zwróci wartość.

Więc pierwszy będzie wolniejszy od drugiego.

Uruchom ten Test: http://jsperf.com/bitwise-logical

W Chrome & IE Bitwise jest wolniejszy ale na Firefoksie logiczny jest wolniejszy

 1
Author: Mostafa Soghandi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-14 09:47:39
var bit1 = (((true & true) & (false & false)) & true), // return 0;
    bit2 = (((true && true) && (false && false)) && true); // return flase

alert(bit1 + ' is not ' + bit2);
 -1
Author: left,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-14 12:15:51