Chciałbym wiedzieć, czy JavaScript ma ocenę „zwarcia”, taką jak && Operator w C #. Jeśli nie, chciałbym wiedzieć, czy istnieje obejście, które ma sens.
Chciałbym wiedzieć, czy JavaScript ma ocenę „zwarcia”, taką jak && Operator w C #. Jeśli nie, chciałbym wiedzieć, czy istnieje obejście, które ma sens.
Odpowiedzi:
Tak, JavaScript ma ocenę „zwarcia”.
if (true == true || foo.foo){
// Passes, no errors because foo isn't defined.
}
if (false && foo.foo){
// Passes, no errors because foo isn't defined.
}
Short-circuit
z tym operatorem logicznym. Po prostu spróbuj sam. Skorzystaj z mojego demo.
Ta odpowiedź zawiera bardzo szczegółowe informacje na temat tego, jak to zrobić zwarciedziała w JavaScript, ze wszystkimi gotcha, a także odpowiednimi motywami, takimi jak pierwszeństwo operatorów, jeśli szukasz szybkiej definicji i już rozumiesz, jak działa zwarcie, polecam sprawdzenie innych odpowiedzi.
Najpierw przyjrzyjmy się zachowaniu, które wszyscy znamy, wewnątrz if()
bloku, w którym używamy &&
do sprawdzenia, czy te dwie rzeczy są true
:
if (true && true) {
console.log('bar');
}
Twoim pierwszym odruchem jest prawdopodobnie powiedzenie: „Ach tak, całkiem proste, kod wykonuje instrukcję, jeśli oba expr1
i expr2
są oceniane jako true
”
Cóż, tak i nie. Jesteś technicznie poprawny, to jest zachowanie, które opisałeś, ale nie tak dokładnie jest oceniany kod i będziemy musieli zagłębić się głębiej, aby w pełni zrozumieć.
&&
i ? ||
:Czas zajrzeć „pod maskę javascript silnik ”. Rozważmy ten praktyczny przykład:
function sanitise(x) {
if (isNaN(x)) {
return NaN;
}
return x;
}
let userinput = 0xFF; // as an example
const res = sanitise(userinput) && userinput + 5
console.log(res);
Wynik jest taki 260
… ale dlaczego? Aby uzyskać odpowiedź, musimy zrozumieć, jak działa ocena zwarcia.
Przez Definicja MDN
&&
operatorexpr1 && expr2
jest wykonywany followingly:Jeśli
expr1
można przekonwertować natrue
, zwracaexpr2
; w przeciwnym razie zwracaexpr1
.
Oznacza to, że w naszym praktycznym przykładzie wartość const res
jest oceniana w następujący sposób:
expr1
-sanitise(0xFF)
0xFF
jest prawidłową liczbą szesnastkową dla 250, w przeciwnym razie zwróciłbym NaN
expr1
Zwrócona wartość „truthy”, czas na wykonanie expr2
(inaczej wpadnę jak NaN
to falsy)userinput
jest truthy (liczba), mogę dodać +5
do niego
- „Prawda” oznacza, że wyrażenie można ocenić jako prawdziwe. Oto lista prawdziwych i fałszywych wyrażeń.
Więc tutaj mogliśmy uniknąć dodatkowych if
blokad i dalszych isNaN
kontroli dzięki prostemu użyciu &&
operatora.
Do tej pory powinniśmy mieć przynajmniej obraz tego, jak plik zwarcieoperatorzy pracują. Uniwersalna zasada brzmi:
(some falsy expression) && expr
oceni do fałszywego wyrażenia(some truthy expression) || expr
oceni do prawdziwego wyrażeniaOto kilka dalszych przykładów dla lepszego zrozumienia:
function a() { console.log('a'); return false; }
function b() { console.log('b'); return true; }
if ( a() && b() ){
console.log('foobar');
}
//Evaluates a() as false, stops execution.
function a() { console.log('a'); return false; }
function b() { console.log('b'); return true; }
if ( a() || b() ){
console.log('foobar');
}
/* 1. Evaluates a() as false
2. So it should execute expr2, which is `b()`
3. b() returned as true, executing statement `console.log('foobar');`
*/
Fajnie, miejmy nadzieję, że zrozumiesz to! Ostatnią rzeczą, którą musimy wiedzieć, jest zasada dotycząca pierwszeństwa operatorów, czyli:
&&
Operator jest zawsze wykonywany przed ||
operatora.Rozważmy następujący przykład:
function a() { console.log('a'); return true;}
function b() { console.log('b'); return false;}
function c() { console.log('c'); return false;}
console.log(a() || b() && c());
// returns a() and stops execution
To powróci jako, być może myląco dla niektórych, jak a()
. Rozum jest dość prosty, tylko wzrok nas zwodzi, ponieważ jesteśmy przyzwyczajeni do czytania od lewej do prawej. Wyjmijmy, console.log()
a co nie, i skupmy się wyłącznie na ocenie
true || false && false
Teraz, aby owinąć głowę wokół tego:
Powiedzieliśmy, że &&
operator ma pierwszeństwo, więc jest oceniany jako pierwszy. Aby pomóc nam lepiej wyobrazić sobie ocenę, pomyśl o definicji
expr1 && expr2
Gdzie:
expr2
jest false
expr1
jest true || false
Więc to była trudna część, teraz true || false
jest oceniana ( expr1
- lewa strona &&
).
||
operator zatrzymuje wykonywanie, jeśli expr1 || expr2
w expr1
oszacuje się jako prawda, expr1
jest wykonywany, a wykonywanie kodu zatrzymuje się.Zwracana wartość to true
Cóż… to było dość trudne, wszystko z powodu kilku dziwnych reguł i semantyki. Pamiętaj jednak, że zawsze możesz uniknąć pierwszeństwa operatora za pomocą ()
- tak jak w matematyce
function a() { console.log('a'); return true;}
function b() { console.log('b'); return false;}
function c() { console.log('c'); return false;}
console.log((a() || b()) && c());
/* 1. The () escape && operator precedence
2. a() is evaluated as false, so expr2 (c()) to be executed
3. c()
*/
expr1
a expr2
lub condition1
czy cokolwiek innego, to jest po prostu mylące. Zdecyduj się na jedną, możesz też wprowadzić zmienne lokalne, np. const expr1 = true; if(expr1 && ...)
https://www.google.com/search?q=site:stackoverflow.com+%s
jako skrót wyszukiwania (Chrome / Firefox), aby przyspieszyć wyszukiwanie.