JavaScript'in "Kısa devre" değerlendirmesi var mı?


106

JavaScript’in C #’da && Operator gibi "kısa devre" değerlendirmesi olup olmadığını öğrenmek istiyorum. Değilse, benimsemenin mantıklı olduğu bir geçici çözüm olup olmadığını bilmek isterim.


2
Rica ederim. https://www.google.com/search?q=site:stackoverflow.com+%sAramaları hızlandırmak için arama kısayolu (Chrome / Firefox) olarak ekledim .
Rob W


Yanıtlar:


123

Evet, JavaScript'in "kısa devre" değerlendirmesi var.

if (true == true || foo.foo){
    // Passes, no errors because foo isn't defined.
}

Canlı DEMO

if (false && foo.foo){
    // Passes, no errors because foo isn't defined.
}

Canlı DEMO


9
Yani kısa devre JS'de standart mı?
GibboK

1
Teşekkürler gdoron, lütfen anlamama yardım et ... C #'da ayrıca & gibi ikili operatörüm var, bunun yerine her iki operand da geçmek için doğru olmalı, bunun yerine C
GibboK

1
@GibboK. O zaman, açıkçası, Short-circuitbu mantık operatörüyle bir olamaz . Sadece kendiniz deneyin. Demomu kullan.
gdoron, Monica'yı

2
@GibboK: Bu operatör referansına bakın . Ve evet, JS'de de bir ikili AND operatörü var.
Bergi

5
@GibboK. EVET standartta! Ancak, javascript uygulamalarında JIT derleme büyüsü zamanlarında olduğu gibi, iyi bir yorum, bir şeyin "standart" olup olmadığını veya potansiyel olarak uygulamaya tabi olup olmadığını gerçekten bilmek ister. İkili Mantıksal Operatörler ile bir koşul ifadesinin değerlendirilme şekli ve (kısa devre) standart bir davranıştır ecma-international.org/ecma-262/5.1/#sec-11.11
humanityANDpeace

26

Bu cevap, nasıl JavaScript ile çalışır, tüm gotcha'larla ve ayrıca operatör önceliği gibi ilgili temalarla çalışır, hızlı bir tanım arıyorsanız ve kısa devrenin nasıl çalıştığını zaten anlıyorsanız, diğer cevapları kontrol etmenizi tavsiye ederim.


Şimdiye kadar bildiklerimiz (sandık):

Öncelikle if()bloğun içinde hepimizin aşina olduğu davranışı inceleyelim , burada &&iki şeyin olup olmadığını kontrol edelim true:

if (true && true) {
   console.log('bar');
} 

Şimdi, ilk içgüdünüz muhtemelen şunu söylemektir: 'Ah evet, oldukça basit, kod, her ikisi de expr1ve expr2olarak değerlendirilirse ifadeyi çalıştırır true'

Hem evet hem hayır. Teknik olarak haklısınız, tanımladığınız davranış budur, ancak bu tam olarak kodun nasıl değerlendirildiği değildir ve tam olarak anlamak için daha derine inmemiz gerekir.


Tam olarak nasıl olduğunu &&ve ||yorumlanır ?:

"Kaputunun altına" bakma zamanı motor ". Şu pratik örneği ele alalım:

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);

Peki sonuç 260... ama neden? Cevabı alabilmek için kısa devre değerlendirmesinin nasıl çalıştığını anlamamız gerekiyor.

By MDN Tanımı&& operatörü expr1 && expr2ve arkasından yürütülür:

Eğer expr1dönüştürülebilir truedönüşleri, expr2; aksi takdirde döner expr1.

Yani bu, bizim pratik örneğimizde const resaşağıdaki şekilde değerlendirildiği anlamına gelir :

  1. Çağırmak expr1-sanitise(0xFF)
  2. 0xFF 250 için geçerli bir onaltılık sayıdır, aksi takdirde döndürürdüm NaN
  3. expr1Bir "truthy" değer döndürdü, zaman yürütmek için expr2 (aksi durdurmak istiyorum NaNfalsy olan)
  4. Yana userinputtruthy (bir numara), ben ekleyebilir +5kendisine
  • "Gerçek", ifadenin doğru olarak değerlendirilebileceği anlamına gelir. İşte doğru ve yanlış ifadelerin bir listesi .

Böylece burada, operatörün basit bir kullanımı ile ek ifbloklardan ve daha fazla isNaNkontrolden kaçınmayı başardık &&.


Gerçekten nasıl çalışıyor:

Şimdiye kadar, en azından nasıl bir operatörler çalışır. Evrensel kural şu ​​şekildedir:

  • (some falsy expression) && expr yanlış ifade olarak değerlendirilecek
  • (some truthy expression) || expr doğru ifadeyle değerlendirecek

İşte daha iyi anlamak için bazı başka örnekler:

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');`
*/


Son bir sinir bozucu, ancak çok önemli şey [Operatör Önceliği]:

Güzel, umarım onu ​​anlıyorsundur! Bilmemiz gereken son şey, operatör önceliğiyle ilgili bir kuraldır, yani:

  • &&Operatör her zaman önce çalıştırılır ||operatörü.

Aşağıdaki örneği düşünün:

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

Bu, belki bazılarına kafa karıştırıcı bir şekilde geri dönecektir a(). Sebep oldukça basit, sadece gözümüz bizi kandırıyor çünkü soldan sağa okumaya alışkınız. Hadi console.log()ve neyi çıkaralım ve tamamen değerlendirmeye odaklanalım

true || false && false

Şimdi kafanızı bunun etrafına sarın:

  1. &&Operatörün önceliği var dedik , bu yüzden ilk olarak değerlendirilir. Değerlendirmeyi daha iyi hayal etmemize yardımcı olmak için tanımı düşünün

    expr1 && expr2
    

    Nerede:

    • expr2 dır-dir false
    • expr1 dır-dir true || false
  2. İşin zor kısmı buydu, şimdi true || falsedeğerlendirildi ( expr1- sol tarafı &&).

    • Verilen ||varsa operatör yürütme durur expr1 || expr2içinde expr1truthy olarak değerlendirir, expr1yürütülen ve kod yürütme durur.
  3. Döndürülen değer true

Şey .. bu oldukça aldatıcıydı, hepsi birkaç tuhaf kural ve anlambilim nedeniyle. Ancak unutmayın, operatör önceliğinden her zaman kaçabilirsiniz ()- tıpkı matematikte olduğu gibi

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()  
*/


Ben 1) "derleyici" kelimesini kullanmazdım. "motor" daha doğrudur. 2) söz değil expr1ve expr2 ya condition1ya da her türlü, bu sadece karıştırıyor. Birine karar verin, yerel değişkenleri de tanıtabilirsiniz, örn. const expr1 = true; if(expr1 && ...)
Jonas Wilms

@JonasWilms girdi için teşekkürler, cevabı buna göre değiştirdi.
Samuel Hulla

1
Bu hala sorulan soruyu doğrudan yanıtlamıyor.
Kevin B

7
Bu şimdiye kadar gördüğüm en iyi "soruya açıkça cevap vermeyen harika cevap" ...
Gerardo Furtado

1
Bu, derin bir açıklamayla doğru cevaptır, kabul edildi olarak işaretlenmeli ve şu anda olduğundan çok daha fazla oylanmalıdır!
Alexander Kim
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.