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-circuitz 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 expr1i expr2są 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 && expr2jest wykonywany followingly:Jeśli
expr1można przekonwertować natrue, zwracaexpr2; w przeciwnym razie zwracaexpr1.
Oznacza to, że w naszym praktycznym przykładzie wartość const resjest oceniana w następujący sposób:
expr1-sanitise(0xFF)0xFF jest prawidłową liczbą szesnastkową dla 250, w przeciwnym razie zwróciłbym NaNexpr1Zwrócona wartość „truthy”, czas na wykonanie expr2 (inaczej wpadnę jak NaNto falsy)userinputjest truthy (liczba), mogę dodać +5do 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 ifblokad i dalszych isNaNkontroli 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 falseexpr1 jest true || falseWięc to była trudna część, teraz true || falsejest oceniana ( expr1- lewa strona &&).
||operator zatrzymuje wykonywanie, jeśli expr1 || expr2w expr1oszacuje się jako prawda, expr1jest 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()
*/
expr1a expr2 lub condition1czy 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+%sjako skrót wyszukiwania (Chrome / Firefox), aby przyspieszyć wyszukiwanie.