Neden mantıksal işleçler için bileşik atama işleçleri yoktur (||, && vb.)?


20

ECMA-262, kısmen 11.13 göre aşağıdaki bileşik atama operatörlerinin ayrıntılı listesi: *= /= %= += -= <<= >>= >>>= &= ^= |=.

Kısmına 11.11 göre, var c = a || bkoyacağız aiçine değeri cise ToBoolean(a)doğrudur ve koyacağız biçine değerini caksi. Bu nedenle, mantıksal OR genellikle birleşme operatörü olarak kullanılır;

function (options) {
    options = options || {};
}

Sıkça yeterli, kaynaşabilecek yukarıdaki gibi gösterildi, değişken için varsayılan değeri belirtmek için kullanılır: a = a || b.

Bileşik atama operatörü gibi görünüyor ||=daha kısa ve daha temiz bir şekilde yukarıdaki kod yazmak için izin gerçekten yararlı olacaktır: a ||= b. (Ancak, her ne orada değil *=, +=başka bileşik atama operatörleri ve).

Soru, neden?


2
% = Operatörünün bile var olması inanılmaz derecede şaşırdım. Bunun gerekli olduğuna kim karar verdi? Bu operatörlerden bazıları kötü dil tasarım kararları gibi görünüyor.
Jonathan Rich

2
@JonathanRich: neden% = yok? Bu atama operatörlerinden herhangi birine sahip olacaksanız, er ya da geç bazı geliştiriciler (penartur gibi) operatörlerin neden diğerlerinden daha "eşit" olduğunu merak edecektir.
kevin cline

4
@JonathanRich Crypto, modülü önemli ölçüde kullanır. Furthemore (aritmetik atama operatörlerine aritmetik geri kalanı ile arzu edilen bir diklik olduğu bir bekliyorsa +=, *=,-= , /=, neden olmaz %=işler?).

4
@JonathanRich: Operatör dairesel bir şeyiniz olduğunda ve normalleştirmek istediğinizde kullanışlı olur, örn. angle %= 360 veya vertexIndex %= numberOfVertices(kapalı bir çokgenin tepe listesi için).
Sebastian Negraszus

Yanıtlar:


12

Olası nedenlerden biri mantıksal operatörlerin &&ve ||"kısa devre" davranışına sahip olmalarıdır. Sağ taraftaki işlenen &&ve ||gerekli olmadıkça değerlendirilmez. Belki de bu nedenle dil tasarımcıları, böyle bir ifadenin anlamının a ||= f()açık olmadığına karar verdiler ve bu tür operatörler daha iyi bırakıldı.


2
Evet. Örneğin, birçok insan a ||= bbunun yorumlanması gerektiğine inanır a = a || b, ancak aslında a || a = b( Ruby'de olduğu gibi ) olabilir. Ayarlayıcının yan etkisi varsa bunlar farklı olabilir . Birini seçmek diğer kamptaki kullanıcılar için kötü olabilir. Şahsen a || a = byolu seviyorum (Ruby yolu), ama herkesin bundan memnun olup olmadığından emin değilim.
Franklin Yu

8

"Bu dil özelliği neden uygulanmadı" ile ilgili tüm soruların genel cevabı, dili tasarlayan ekibin, avantajın maliyetten daha ağır basmadığına karar vermesidir.

Maliyet birçok şekilde olabilir. Bir dil özelliğini uygulamak zaman ve çaba gerektirir, ancak aynı zamanda karmaşık karmaşıklığın maliyeti de vardır: özellik, dili potansiyel faydasıyla orantılı olarak daha karmaşık veya belirsiz kılıyor mu?

Varsayımsal ||=operatör diğer bileşik atama operatörlerinden temelde farklı bir şey yapar. Diğer operatörler doğası gereği tamamen matematiksel olsa da, bu farklıdır: bir değeri diğerinin yerine (tarif ettiğiniz bağlamda) koyar.

Bu belirsizlik göz önüne alındığında (operatör bağlama bağlı olarak iki farklı işlev gerçekleştirir ), neden dile dahil edilmediğini görmek zor değildir. Her ne kadar değiştiğini

function (options) {
    options = options || {};
}

için

function (options) {
    options ||= {};
}

null birleştirme yapmak değerli bir özelliktir, fayda benim için çok daha az açıktır. Değer ikamesi gerçekleşecekse, her iki değere sahip olmak mantıklı (ve daha net) görünmektedir ikamenin meydana gelebileceğine dair görsel bir gösterge sağlamak de eşittir işaretinin sağ tarafında .

C # farklı bir yol izledi ve boş birleştirme için belirli bir işleç kullanıyor .


1
Kodu okurken, oradaki ilk örnek daha doğal bir şekilde okur - "seçenekler seçeneklere eşit veya hiçbir şey" - ikincisine kıyasla - "seçenekler veya hiçbir şeye eşit değildir". Bence bu "veya eşittir" operatörünü dahil etmemenin başka bir nedeni
Andy Hunt

Cevabınıza mükemmel açılış. Sanırım cevabınızın başlangıcı etiket için wiki'ye ait.

3
@AndyBursh Aynı mantık herhangi bir bileşik atama operatörüne uygulanabilir. "X, X çarpı 2'ye eşittir", "X çarpı 2'ye eşittir" ile karşılaştırıldığında daha doğal okur.
Penartur

2
Yazmanın iki kez yazmanızı foo = foo || bargerektirdiğini unutmayın foo. Bu hem hantal hem de yazım hatalarını yeniden düzenleme eğilimindedir.
Phrogz

1
Bence "matematiksel" anlamını yanlış anlıyorsunuz, belki de boole cebirini duymuşsunuzdur. ||=Bir boş birleştirici operatör olarak kullanmak için bir boolean olmayan zorlamanın sezgisel olmadığını ve aslında kod biçiminde geniş göründüğünü kabul ediyorum . Yararlı hale geldiği yer, boolean matematiği yapmaya çalıştığınızdadır. function fulfill(inValue) { if(resolved || rejected) return false; /* Do stuff here */ return true; } resolved ||= fulfill(value)
joshperry

3

Haklısın bu ||=yararlı bir yapı. Perl.

Aslında Perl bunların hepsini kullanılabilir kılıyor :

**=    +=    *=    &=    <<=    &&=   -=    /=    
|=     >>=   ||=   .=    %=     ^=    //=   x=

Bunlardan bazıları harika ( .=bir dizenin sonuna bir şey ekler), diğerleri daha az ( &&=??? Her ikisinin ve değişkenin doğru olması durumunda değişkenin sağ tarafa ayarlanacağını varsayalım. ?)

Bir dile dahil olan şey aslında tasarım felsefesinin bir özelliğidir.


3
stackoverflow.com/questions/12589467/… ne &&=anlama geldiğini / ne anlama geldiğini öğrenmek için .
Mat
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.