JavaScript lub (||) Wyjaśnienie przypisania zmiennej

Biorąc pod uwagę ten fragment JavaScript...

var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';

var f = a || b || c || d || e;

alert(f); // 4
Czy ktoś może mi wyjaśnić, jak nazywa się ta technika (najlepiej zgaduję w tytule tego pytania!)? I jak/dlaczego dokładnie to działa?

Rozumiem, że zmienna f zostanie przypisana najbliższa wartość (od lewej do prawej) pierwszej zmiennej, która ma wartość, która nie jest ani null, ani undefined, ale nie udało mi się znaleźć wiele materiałów referencyjnych na temat tej techniki i widziałem, jak używała Nr serii

Czy ta technika jest specyficzna dla JavaScript? Wiem, że zrobienie czegoś podobnego w PHP spowodowałoby, że f ma prawdziwą wartość logiczną, a nie samą wartość d.

Author: Bergi, 2010-01-20

12 answers

Zobacz ocena zwarcia dla wyjaśnienia. Jest to powszechny sposób implementacji tych operatorów; nie jest unikalny dla JavaScript.

 174
Author: unwind,
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
2012-02-05 20:43:26

Służy do przypisania wartości domyślnej , w tym przypadku wartości y, jeśli zmienna x jest falsy.

Operatory logiczne w JavaScript mogą zwracać operand, a nie zawsze wynik logiczny, jak w innych językach.

Operator logiczny or (||) Zwraca wartość swojego drugiego operanda, jeśli pierwszy jest fałszywy, w przeciwnym razie zwracana jest wartość pierwszego operanda.

Na przykład:

"foo" || "bar"; // returns "foo"
false || "bar"; // returns "bar"

Falsy wartości są tymi, które wymuszają false, gdy są używane w kontekście logicznym i są 0, null, undefined, pusty łańcuch NaN i oczywiście false.

 152
Author: CMS,
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
2010-06-21 20:11:51

Javacript używa oceny zwarcia dla operatorów logicznych || i &&. różni się jednak od innych języków tym, że zwraca wynik ostatniej wartości, która wstrzymała wykonanie, zamiast wartości true lub false.

Następujące wartości są uważane za falsy w JavaScript.

  • false
  • null
  • "" (pusty łańcuch)
  • 0
  • Nan
  • undefined

Ignorowanie Operator precedence zasady, i utrzymanie rzeczy proste, poniższe przykłady pokazują, która wartość zatrzymała ocenę i zostanie zwrócona w wyniku.

false || null || "" || 0 || NaN || "Hello" || undefined // "Hello"

Pierwsze 5 wartości do NaN są falsy, więc wszystkie są oceniane od lewej do prawej, dopóki nie spełnia pierwszej wartości true - "Hello" co czyni całe wyrażenie prawdziwym, więc cokolwiek dalej nie będzie oceniane, a "Hello" zostanie zwrócone jako wynik wyrażenia. Podobnie, w tym case:

1 && [] && {} && true && "World" && null && 2010 // null

Pierwsze 5 wartości są prawdziwe i są oceniane, dopóki nie spełnia pierwszej wartości falsy (null), co sprawia, że wyrażenie jest fałszywe, więc {[13] }nie jest już oceniane, a null jest zwracane jako wynik wyrażenia.

Przykład, który podałeś, to użycie tej właściwości JavaScript do wykonania przypisania. Może być używany wszędzie tam, gdzie trzeba uzyskać pierwszą wartość prawdziwości lub fałszu wśród zestawu wartości. Poniższy kod przypisze wartość "Hello" do b, ponieważ ułatwia przypisanie domyślnej wartości, zamiast sprawdzania if-else.

var a = false;
var b = a || "Hello";

Poniższy przykład można nazwać eksploatacją tej funkcji i uważam, że utrudnia to czytanie kodu.

var messages = 0;
var newMessagesText = "You have " + messages + " messages.";
var noNewMessagesText = "Sorry, you have no new messages.";
alert((messages && newMessagesText) || noNewMessagesText);

Wewnątrz alertu sprawdzamy, czy messages jest falsy, a jeśli tak, to ewaluujemy i zwracamy noNewMessagesText, w przeciwnym razie ewaluujemy i zwracamy newMessagesText. Ponieważ w tym przykładzie jest to fałszywe, zatrzymujemy się na noNewMessagesText i alert "Sorry, you have no new messages.".

 104
Author: Anurag,
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
2018-07-14 13:37:39

Zmienne Javascript nie są wpisywane, więc f może być przypisana wartość całkowita, nawet jeśli została przypisana przez operatory logiczne.

F jest przypisana najbliższa wartość, która jest nie równoważna false . Tak więc 0, false, null, undefined są wszystkie przekazywane:

alert(null || undefined || false || '' || 0 || 4 || 'bar'); // alerts '4'
 41
Author: Alsciende,
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
2016-06-06 09:39:03

Nie ma w tym żadnej magii. Wyrażenia logiczne takie jak a || b || c || d są leniwie oceniane. Interpeter szuka wartości a, jest niezdefiniowany, więc jest fałszywy, więc porusza się dalej, potem widzi b, która jest null, która nadal daje fałszywy wynik, więc porusza się dalej, a następnie widzi c - tę samą historię. W końcu widzi d i mówi "huh, to nie jest null, więc mam swój wynik" i przypisuje go do ostatecznej zmiennej.

Ta sztuczka będzie działać we wszystkich językach dynamicznych, które wykonują leniwe zwarcie wyrażeń logicznych. W językach statycznych nie kompiluje się (błąd typu). W językach, które są chętne do oceniania wyrażeń logicznych, zwróci wartość logiczną (tj. true w tym przypadku).

 30
Author: Marcin,
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
2010-01-20 10:58:21

To pytanie otrzymało już kilka dobrych odpowiedzi.

Podsumowując, technika ta wykorzystuje cechę kompilacji języka. Oznacza to, że JavaScript "zwiera" ewaluację operatorów logicznych i zwraca wartość powiązaną z pierwszą Nie fałszywą wartością zmiennej lub dowolną ostatnią zmienną. Zobacz Wyjaśnienie Anurag tych wartości, które zostaną ocenione NA false.

Stosowanie tej techniki nie jest dobrą praktyką dla kilka powodów; jednak.

  1. czytelność kodu: używa się operatorów logicznych, a jeśli zachowanie kompilacji nie jest zrozumiałe, to oczekiwanym wynikiem będzie wartość logiczna.
  2. stabilność: jest to użycie funkcji kompilacji języka, która jest niespójna w wielu językach, a dzięki temu jest to coś, co potencjalnie może być ukierunkowane na zmiany w przyszłości.
  3. Udokumentowane funkcje: istnieje alternatywa to odpowiada tej potrzebie i jest spójne w wielu językach. Byłby to operator trójdzielny:

    () ? wartość 1: Wartość 2.

Użycie operatora trójdzielnego wymaga trochę więcej typowania, ale wyraźnie rozróżnia między obliczanym wyrażeniem logicznym a przypisywaną wartością. Ponadto może być przykuta łańcuchowo, więc typy domyślnych przydziałów wykonywane powyżej mogą być odtworzone.

var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';

var f =  ( a ) ? a : 
                ( b ) ? b :
                       ( c ) ? c :
                              ( d ) ? d :
                                      e;

alert(f); // 4
 9
Author: WSimpson,
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
2016-06-03 14:19:53

Return output first true value.

If all are false return last false value.

Przykład:-

  null || undefined || false || 0 || 'apple'  // Return apple
 5
Author: Arshid KV,
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
2016-03-15 12:20:02

Ustawia nową zmienną (z) na wartość x jeśli jest "prawdziwa" (niezerowa, poprawny obiekt/tablica/funkcja/cokolwiek to jest) lub y w przeciwnym razie. Jest to stosunkowo popularny sposób dostarczania wartości domyślnej w przypadku, gdy x nie istnieje.

Na przykład, jeśli masz funkcję, która pobiera opcjonalny parametr wywołania zwrotnego, możesz podać domyślne wywołanie zwrotne, które nic nie robi:

function doSomething(data, callback) {
    callback = callback || function() {};
    // do stuff with data
    callback(); // callback will always exist
}
 4
Author: Matthew Crumley,
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
2010-06-21 20:13:32

Oznacza to, że jeśli x jest ustawiona, to wartość dla z będzie x, w przeciwnym razie Jeśli y jest ustawiona, to jej wartość będzie ustawiona jako wartość z.

To to samo co

if(x)
  z = x;
else
  z = y;

Jest to możliwe, ponieważ operatory logiczne w JavaScript nie zwracają wartości logicznych, ale wartość ostatniego elementu potrzebnego do wykonania operacji(w zdaniu OR będzie to pierwsza Nie-fałszywa wartość, w zdaniu AND będzie to ostatnia). Jeśli operacja się nie powiedzie, to false jest zwrócony.

 1
Author: Andris,
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
2010-06-21 20:23:20

Nazywa się operatorem zwarcia.

Ocena zwarcia mówi, że drugi argument jest wykonywany lub oceniany tylko wtedy, gdy pierwszy argument nie wystarcza do określenia wartości wyrażenia. gdy pierwszy argument funkcji OR ( / / ) zostanie obliczony na true, ogólna wartość musi być true.

Może być również użyty do ustawienia domyślnej wartości argumentu funkcji.`

function theSameOldFoo(name){ 
  name = name || 'Bar' ;
  console.log("My best friend's name is " + name);
}
theSameOldFoo();  // My best friend's name is Bar
theSameOldFoo('Bhaskar');  // My best friend's name is Bhaskar`
 1
Author: Vijay,
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
2017-12-22 11:17:19

Obliczy X i, jeśli X nie jest null, pusty łańcuch lub 0 (logiczny fałsz), to przypisze go do z. Jeśli X jest null, pusty łańcuch lub 0( logiczny fałsz), to przypisze y do z.

var x = '';
var y = 'bob';
var z = x || y;
alert(z);

Wyświetli 'bob';

 0
Author: tvanfosson,
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
2010-09-27 17:02:22

Zgodnie z Bill Higgins' blog post; Javascript logiczne lub przypisanie idiom (luty. 2007), to zachowanie jest prawdziwe od wersji 1.2 (co najmniej)

Sugeruje również inne wykorzystanie go (cytowany): " lekka normalizacja różnic między przeglądarkami "

// determine upon which element a Javascript event (e) occurred
var target = /*w3c*/ e.target || /*IE*/ e.srcElement;
 0
Author: Alon Brontman,
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
2012-12-21 18:14:25