2014-12-20 16 views
5

Dowiedziałem się na własnej skórze, że operatory bitowe na boolach nie zwracają wartości w JavaScript. Myślałem, że to błąd, ale sprawdziłem to w specyfikacji ECMAScript i na pewno mówi, że operatory bitowe zwracają liczby, a nie boole. Nie mówi ani słowa o dziwactwie, które powstaje, gdy używasz ich na wartościach boolowskich. Dlaczego tak się dzieje? Używam tej techniki od lat w innych językach, więc jestem całkowicie zaskoczony, dlaczego robi coś innego w JavaScript. Jakieś pomysły? Czy to dlatego, że nikt nie używa w ten sposób operatorów bitowych (oprócz mnie), czy jest jakiś techniczny powód? Nie mogę sobie wyobrazić, że trudno byłoby sprawdzić typ i zwrócić wartość boolowską.JavaScript: dlaczego bitowe LUB z bajtów zwraca liczbę zamiast wartości boolowskiej?

Dla porównania, następujący kod:

var found = false; 
console.log(found, typeof(found)); 

found |= true; 
console.log(found, typeof(found)); 

found = true; 
console.log(found, typeof(found)); 

Produkuje następujący wynik:

false 'boolean' 
1 'number' 
true 'boolean' 

Edit:

Wnioskiem, użyłem tego w C, C++, a ja jestem całkiem pewien PHP, chociaż nie chciałbym na to przysięgać. Tak, zdaję sobie sprawę, że C/C++ są pisane na maszynie, więc byłoby inaczej wewnętrznie. Zastanawiam się, dlaczego JavaScript zachowałby się inaczej.

Na życzenie, przykładem, jak bym zazwyczaj używają | =

var foundLowest = false; 

for(var k = 0; k < someLength; ++k) { 
    foundLowest |= someFunctionThatReturnsTF(k); 
} 

if(foundLowest === true) { 
    /* do stuff */ 
} 
+1

Może dodasz jakąś próbkę przypadku rzeczywiste użytkowanie '|' lub '&' na wartościach logicznych? –

+0

Jeśli o to chodzi, to w jakim języku mówisz '| =' z bajtami? –

+0

Wyobrażam sobie operacje bitowe, aby zawsze zwracać wartości liczbowe, nawet dla wartości logicznych; biorąc pod uwagę kaptur, utożsamiają się z numerycznymi. Dlaczego spodziewałbyś się wartości zwracanej przez boolean? –

Odpowiedz

6

posiadające bitowe operatorzy zachowują się konsekwentnie (zawsze konwertowania ich argumentów do liczb) wydaje się być wystarczająco dobry powód, żeby zostać określony, jakie one są. Kilka lat temu była dyskusja na temat listy dyskusyjnej o dodaniu ||= i podobnych skrótowych operatorów, ale Eich   &   Co są bardzo konserwatywni w dodawaniu takich rzeczy i wydaje mi się, że przypominają komentarz o tym, że "nie" t wyciągnąć swoją wagę składniową. " :-)

Zauważ, że JavaScript jest szczęśliwy, aby zmusić żadnej wartości do wartości logicznej, można użyć stylu szczęśliwie aktualne i mają nadal pracować, ponieważ true wymusza na 1 przekształcająca się true i false wymusza na 0 który coerces do false. Np .:

var a = false; 
 

 
a |= true; 
 
// Even though `a` is now `1`, it works just fine 
 
if (a) { 
 
    snippet.log(a + " => if branch"); // Does this one 
 
} else { 
 
    snippet.log(a + " => else branch"); 
 
} 
 

 
a &= false; 
 
// Even though `a` is now `0`, it works just fine 
 
if (a) { 
 
    snippet.log(a + " => if branch"); 
 
} else { 
 
    snippet.log(a + " => else branch"); // Does this one 
 
}
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

+0

Hehe, tak, jestem po prostu paranoikiem na temat przymusu. Używam bezpiecznych operatorów równości/nierówności, a ja mam jshint, gdy zapomnę. Chyba jestem zawieszony w C/C++.Zwłaszcza C++, z milionem różnych sposobów, które niejawne konwersje z konstruktorami mogą wpędzić cię w kłopoty. – GreatBigBore

+1

@GreatBigBore: Naprót typu może być skomplikowany, ale jego podział prawdy/falseta jest bardzo prosty: wartoś ci falsey to '0',' NaN', '" "', 'null',' undefined', oraz Oczywiście, "fałsz"; wszystko inne jest prawdą. –