Birden fazla koşul içeren bir ifade, hepsini test eden bir javascript mi?


100

Javascript'te, test etmek için birden fazla koşul içeren bir if ifadesi kullanırken, javascript hepsini ne olursa olsun test eder mi, yoksa zaten yanlışsa hepsini test etmeden önce kurtarır mı?

Örneğin:

 a = 1
 b = 2
 c = 1

 if (a==1 && b==1 && c==1)

Javascript bu koşulların 3'ü için de test yapacak mı yoksa b'nin 1'e eşit olmadığını ve dolayısıyla yanlış olduğunu gördükten sonra ifadeden çıkar mı?

Performans açısından soruyorum. Örneğin, 3 karmaşık jQuery seçiciyi test ediyorsam, jQuery'nin, YANLIŞ döndüreceği ilkinden açıkça belliyse, DOM'u 3 kez taramasını tercih etmem. (Bu durumda, ifadeleri 3'ü iç içe geçirmek daha mantıklı olacaktır).

EK: Meraktan daha fazlası, bunun için uygun terim nedir? Çoğunuzun 'kısa devre' terimini kullandığını fark ettim. Ayrıca, bazı diller bunu yapıyor ve diğerleri yapmıyor mu?


@Josh: Bunun mikro optimizasyon olduğu fikrini tamamen takdir ediyorum. Hangisini bilmek güzel. Bununla birlikte, bir seçenek diğerinden daha optimize edilmişse, söz konusu yöntemi bilmenin ve alışkanlık edinmenin iyi olduğunu varsayıyorum. (Artı, yanıtı da gerçekten merak ediyordum)
DA.

21
Açıkçası, bu erken bir optimizasyon değil. Kısa devre mantığı olan dillerde, bazı yöntemlerin hangi koşullar altında çalıştırılmayacağını bilmek önemlidir; Örneğin, yan etkilerine güveniyorsanız.
Rob

5
İşte "kısa devre değerlendirmesi" hakkında başka bir soru: stackoverflow.com/questions/1232603/…
David

@David. Teşekkürler! İlginç bir okuma.
DA.

Yanıtlar:


151

&&Operatör "kısa devre" - Sol Koşul yanlışsa olduğunu, bunun doğru bir değerlendirmeye rahatsız etmez.

Benzer şekilde, ||sol koşul doğruysa operatör kısa devre yapar.

DÜZENLEME: Yine de, kıyaslama yapıp bunun bir sorun olduğunu belirleyene kadar performans konusunda endişelenmemelisiniz. Erken mikro optimizasyon, sürdürülebilirliğin sıkıntısıdır.


1
Mükemmel cevap (hem teknik kısım hem de yönetim sorunu). Teşekkürler!
DA.

5
Boole ifadesinin tüm bölümlerini yürütmesini İSTEDİĞİNİZDE & ve | ve ve / veya tekrarlayıcı olarak
Zoidberg

25
Bu koşul her zaman performansla ilgili değildir. Bazen bir boş kontrol yapıyor olabilirsiniz ve boş kontrolünüzün a koşulu olup olmadığını söyleyebilirsiniz ve sonra ikinci kontrolünüz için a (b == değer + 1) yapmayı denerseniz, koşulların tamamı kontrol edilirse, üç koşulun tamamı kontrol edilirse bir hata alırsınız.
08'de infocyde

4
Aslında, kısa devre performansla ilgili değildir. Ancak asıl soru performans açısından sormaktı.
Anon.

1
çok iyi. Bu tür bir mikro optimizasyonu (diğerlerinin yanı sıra) yapmak, bir kaydırma olayı döngüsü içinde büyük bir etkiye sahip olabilir, örneğin birden çok öğenin paralaks hesaplaması veya hatta yapışkan çubuk için diyelim. bunu örnek olarak ele alalım: if (!barSticky && bar.parent().offset().top <= document.documentElement.scrollTop)ikinci koşul daha maliyetli bir hesaplamadır, ilki sadece bir boolean. :)
antoni

13

Performans açısından bakıldığında, bu bir mikro optimizasyon değildir.

3 Boole değişkenimiz varsa, a, b, c bu bir mikro optimizasyondur.

Boole değişkenlerini döndüren 3 fonksiyon çağırırsak, her fonksiyon uzun zaman alabilir ve sadece bu kısa devreleri bilmek değil, hangi sırayla bilmek önemlidir. Örneğin:

if (takesSeconds() && takesMinutes())

şundan çok daha iyi

if (takesMinutes() && takesSeconds())

her ikisi de eşit derecede yanlış döndürüyorsa.


12

Bu yüzden javascript kodunda şöyle yapabilirsiniz:

var x = x || 2;

Bu, x tanımsız veya başka bir şekilde 'yanlış' ise varsayılan değerin 2 olduğu anlamına gelir.


3
JS kısa devre değerlendirmesini desteklemese bile bu işe yarayabilir.
pswg

1
Bu bir üçlüye eşdeğer mi?
Mark Carpenter Jr

10

Birinin tüm koşulların değerlendirilmesini zorlamanın bir yolu olup olmadığını merak etmesi durumunda, bazı durumlarda bitsel operatörler kullanılabilir &ve |kullanılabilir.

var testOr = true | alert(""); //alert pops up
var testAnd = false & alert(""); //alert pops up

Bunlar gerçekten dikkatli kullanılmalıdır çünkü bitsel operatörler, işlenenlerinin tek bitleri üzerinde çalışan aritmetik operatörlerdir ve her zaman "kısa devre olmayan" &&ve||

Misal:

-2147483648 && 1 = 1 

fakat

-2147483648 & 1 = 0

Umarım buraya gelen birine bunun gibi bilgileri aramaya yardımcı olur (benim gibi) ve düzeltme ve karşı örnek için @Max'a teşekkürler


1
Bu cevap yanlış. & ve | bitsel operatördür, '&& ve ||' nin kısa devre olmayan sürümleri DEĞİLDİR. Bitsel operatörler, işlenenlerinin tek bitleri üzerinde çalışan aritmetik operatörlerdir. Örnek: -2147483648 && 1 = 1 ancak -2147483648 & burada 1 = 0. diğer bilgiler: en.wikipedia.org/wiki/Bitwise_operation
Max

1
@Max aslında bunu bilmiyordum, C'yi çalıştığımdan beri bunu kullanıyorum (şimdi "hile" diyorum) Neyse ki kodumu bozacak bu tür girdiler hiç gelmedi. Cevabımı düzelttim, size borçluyum
ivcandela

@DJDaveMark özür dilerim false && (alert(""))çözümünüzü işe alamadım : /
ivcandela

@ivcandela Ben de yapamazdım. Telefonumda olmasaydım ilk önce test ederdim; o) Yazık ki yorumları düzenleyemezsin. Onu sildim ve aşağıya bir tane daha ekledim
DJDaveMark

Değerlendirmeyi zorlamanın daha basit ve daha iyi yolu, sonuçları değişkenlere kaydetmek ve ardından değişkenlere karşı test etmektir, yani:var a=false; var b=check(); alert(a && b);
DJDaveMark

7

Yalnızca ilk koşullar doğruysa tüm koşulları test eder, kendiniz için test edin:

javascript: alert (false && alert("A") && false);

3

Kısa devre yapar - örneğinizde yalnızca a ve b karşılaştırılacaktır.


3

Soldaki 1 veya daha fazla parametre ile değerlendirmeyi durdurmanın bir başka nedeni.

eğer (response.authResponse && (response.authResponse.accessToken! = user.accessToken)) {...}

ikinci değerlendirme ilkinin doğru olmasına dayanır ve ilk koşul başarısız olduğu için response.authResponse null veya tanımsız ise vb. bir derleme hatası vermez.

Diğer dillerde ilk günlerde bu sorun vardı ve bence artık derleyiciler oluşturmada standart bir yaklaşım.


2

B'nin bire eşit olmadığını gördükten sonra çıkar.


2

Bu sorudaki herhangi birinin kafası karışmış, çünkü ||bir ?operatörle bir arada kullanırken kısa devre davranışını görmüyorlar :

x = 1 || true ? 2 : 3 // value of x will be 2, rather than 1 as expected

kısa devre kuralı çalışmıyor gibi görünüyor. ||Birincisi doğruyken (doğru? 2: 3) ' ün ikinci terimini neden değerlendiriyor ? Bir işlem sırası problemi olduğu ortaya çıkıyor çünkü yukarıdakiler eşdeğerdir

x = (1 || true) ? 2 : 3

ile ||ilk olarak değerlendirilir ve ?ikinci değerlendirildi. Muhtemelen isteyeceğiniz şey:

x = 1 || (true ? 2 : 3)

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.