Özel özelliklere sahip bir JS Booleanı kötü bir uygulama mı?


41

JS'de, özel özelliklere sahip bir Boole döndürebilirsiniz. Örneğin. Modernizr video desteğini test ettiğinde döner trueveya geri döner falseBoolean (Bool, JS'deki birinci sınıf nesnedir) hangi formatların desteklendiğini belirleyen özelliklere sahiptir. İlk başta beni biraz şaşırttı ama sonra fikirden hoşlanmaya başladım ve neden oldukça sık kullanıldıklarını merak etmeye başladım?

Temelde bir şeyin doğru mu yanlış mı olduğunu bilmek istediğiniz tüm senaryolarla başa çıkmanın zarif bir yolu gibi gözükse de, özel bir dönüş nesnesi tanımlamak veya tanımlanmış bir geri arama işlevi kullanmadan tanımlayabileceğiniz bazı ek bilgilerle ilgilenebilirsiniz. daha fazla parametre kabul et. Bu şekilde, daha karmaşık verileri döndürme kapasitesinden ödün vermeden çok evrensel bir işlev imzasını saklarsınız.

Hayal edebileceğim buna karşı 3 argüman var:

  1. Herhangi bir arayüzün net olması ve aldatıcı olmaması için muhtemelen daha iyi olması biraz nadir / beklenmeyen bir durumdur.
  2. Bu, sert bir adam argümanı olabilir, ancak biraz uçtan küçük bir vaka olduğu için, bazı JS optimizer, uglifier, VM'de veya küçük bir temizleme dili belirtimi değişikliğinden sonra sessizce geri teptiğini hayal edebiliyorum.
  3. Aynısını yapmanın daha iyi - özlü, açık ve ortak - yolu vardır.

Öyleyse sorum, Boolean'ları ek özelliklerle kullanmaktan kaçınmak için güçlü nedenler var mı? Bir numara mı yoksa bir hediye mi?


Arsa bükülme uyarısı.

Yukarıda tam şanlı orijinal soru. Matthew Crumley ve senevoldsen'in her ikisinin de işaret ettiği gibi, sahte (sahte) bir öncül dayanmaktadır. İyi JS geleneğinde Modernizr'in yaptığı şey bir dil numarası ve kirli bir şeydir. Propsiyon eklemek için TRYING'den sonra bile yanlış kalacak olan ilkel bir bool olan JS'ye kaynar ve özel propsiyonlara sahip olan ancak bir nesne olmak her zaman harikulade olan bir Boole nesnesidir. Modernizr, ya boolean false ya da hakikaten bir Boolean nesnesi döndürür.

Asıl sorum hilenin farklı şekilde çalıştığını ve bu yüzden en popüler cevapların kodlama standartlarını (kusursuz biçimde geçerli) yönünü ele aldığını varsayıyordu. Ancak tüm hileyi en iyi şekilde sorgulayan cevapları en faydalı buluyorum (ve ayrıca yöntemi kullanmaya karşı nihai argümanları da) bu yüzden onlardan birini kabul ediyorum. Tüm katılımcılara teşekkürler!


35
Boolean tipini genişletmek klasik bir wtf'dir .
hlovdal

7
JS’de, nulldesteklenmezse yeni dönebileceklerini ve eğer öyleyse bir dizi biçimin olabileceğini unutmayın . Bir liste JS'de truthy olarak kabul edilir ve nullsahtedir.
jpmc26


3
Bu soruyu cevaplamadan önce: javascript'te "boolean" ile "Boolean" arasında büyük bir fark vardır. Aynı şeyler değiller ve Boolean'ı büyük harf yapmayan herhangi bir cevap geçersiz.
Pieter B

2
Böyle bir şeyi vahşi doğada, Modernizr kadar popüler bir kütüphanede görmeye mahkum olanlar için
Chris Nielsen

Yanıtlar:


38

Genel tasarım ilkelerine ek olarak, tek sorumluluk ve en az sürpriz gibi, bunun iyi bir fikir olmaması için JavaScript'e özgü bir neden var: a booleanve BooleanJavaScript arasında genel durumda çalışmasını önleyen çok büyük bir fark var .

booleannesne değil ilkel bir türdür ve özel özelliklere sahip olamaz. İfadeler true.toString()iş gibi çünkü perde arkasına dönüşüyor (new Boolean(true)).toString().

Boolean(Bir sermaye B ile birlikte) olan bir nesne, ama çok az iyi kullanım alanı vardır, ve bir olarak kullanılıyor booleankesinlikle bunlardan biri değil. Bunun nedeni , değerinden bağımsız olarak herkesin Boolean"gerçek" olmasıdır , çünkü tüm nesneler truebir boole bağlamında dönüştürülür . Örneğin, şunu deneyin:

var answer = new Boolean(false);
if (answer) {
  console.log("That was unexpected.");
}

Bu nedenle, genel olarak, bir mantıksal olarak hareket etmesine izin veren JavaScript'te bir boole özellikler eklemenin bir yolu yoktur. Modernizr bununla başa çıkabiliyor çünkü yalnızca "gerçek" değerlere özellikler ekliyorsunuz, bu sizin nasıl bir iş beklersiniz (yani if ​​ifadelerinde çalışıyorlar). Video hiç desteklenmiyorsa, Modernizr.videogerçek olacak boolean(değeriyle birlikte false) ve ona eklenen özellikler olamaz.


18
Modernizr'in yaklaşımını oldukça tuhaf buluyorum, sadece trueşartlı olarak değerlendirilen özelliklere sahip bir nesneye sahip olduğumuzu düşünerek . Neden açıkça a kullanıyorsunuz Boolean?
Arturo Torres Sánchez

Sağlam bir teknik tartışma için çok teşekkürler. Hızlı testimin hatalı olduğu anlaşılıyor : jsbin.com/hurebi/3/edit?js,console . Özel sahne ekledikten sonra bile falsekesinlikle 'yanlış' ve sahtedir ( ===ve aynı şekilde ==çalışır) AMA gerçekten ilkel bool'a sahne ekleyemezsiniz. Bool ve bool arasındaki ayrım beni açıkça belli etti.
konrad

@ ArturoTorresSánchez çünkü bunu yaptıkları gibi geri dönüş değerleri aynı tiptedir.
Jared Smith

1
@ ArturoTorresSánchez bu yüzden "nominal olarak" niteleyicisini ekledim: P
Jared Smith

1
@konrad Başvuru için, varsayılan olarak JavaScript, yapmaya çalıştığınızda şikayet etmeyerek ilkellere özellikler eklemenize izin veriyor gibi davranır. Sıkı kip kullanmak, sorunu çözecek veTypeError bir özellik eklemeye çalışırsanız bir atar (bkz. Jsbin.com/yovasafibo/edit?js,console ).
Matthew Crumley

59

Tebrikler, nesneleri keşfettiniz. Bunu yapmama sebebine en az şaşkınlık ilkesi denir . Bir tasarımdan şaşırmak iyi bir şey değildir.

Bu bilgiyi bir araya getirmenin yanlış bir tarafı yok ama neden bir Bool'da saklamak istiyorsunuz? Tüm bu bilgilere sahip olmayı beklediğiniz bir şeye koyun. Bool dahil.


1
LOL evet Sorumu bariz bir alternatif olarak belirttim En az şaşkınlık ilkesi, JS ile zayıf yazma nesneleri daha az şaşırtıcı olsa da hala kafa karıştırıcı olsa ve yine de belgeleri kontrol etmeniz gerekse de iyi bir nokta. Modernizr kullanımına gelince iyi bir örnektir: Tek tip doğru / yanlış sonucu olan geniş bir test grubuna sahipsiniz ve sadece şimdi ve sonra daha fazla bilgi aktarmanız gerekiyor - belki daha sonra gelebilecek olanlara bile ihtiyaç duyuyorsunuz. Tüm kütüphanede büyük değişiklikler yaparak booleanların etrafında fazla miktarda sarıcı ya da bool'u arttırırsınız. IMO o kadar aptal değil.
konrad

1
Kullanım hakkında biraz daha. Bir boole değeri döndürmeye devam ederseniz, herhangi bir (), tümü (), filtre () gibi işlemleri listelemek için tüm işlevleri kolayca geçebilirsiniz. JS’de biraz sıradışı olma pahasına güçlü yazım ya da biçimsel arayüzlerin yoksunluğunu ortadan kaldırıyor - bu ana kadar tartışmasız görünüyor.
konrad

1
"Sıradışı" bana güçlü bir argüman gibi görünmüyor.
Robert Harvey

Soruyu değiştirdim. İşte en az şaşkınlık ilkesine. :-)
konrad

16

Öyle karşı ana argüman bu gecikmenin, tek sorumluluk ilkesi şey ise, bir boolean sadece demeliyim trueveya falsenedenleri ve nasıl ya da başka bir şey. Benim kesin inancım ve pratiğim, bu veya başka herhangi bir bilgiyi iletmek için başka nesnelerin kullanılması gerektiği.


javascript'te Boole veya Boole (B harfiyle) demek istiyorsun.
Pieter B

Ancak, bunu tanımlayan bir nesneniz varsa ve diğer bazı şeylerin aynı prensipleri ihlal ettiği tartışılmaz mı?
Casey

1
@Casey Hayır, bu nesnenin amacı orijinal boolenden farklı olacaktır. Ve örneğin bir işlemin durumunu ve nedenini bildirmek tek bir sorumluluğa sahip olacaktır.
J. Pichardo

1
@Bu sorun şu ki, bu bilgiyi tek başına içeren SRP ihlali değildir. Bu, yalnızca bir boolinin zaten doğru veya yanlışı temsil etmesi sorumluluğuyla birleştiğinde sorun olur. BooleanYine de JavaScript'in shenaniganları.
Jacob Raihle

10

Buna bir boolean değeri denmesinin nedeni, doğru ya da yanlış olduğu gerçeği olduğu için, bu düşünceyi beğenmedim, çünkü tüm amacını wikipedia'dan tamamen baltalıyorsunuz.

Bilgisayar bilimlerinde, Boolean veri türü, mantık ve Boolean cebirinin doğruluk değerlerini temsil etmeyi amaçlayan iki değeri (genellikle doğru ve yanlış olarak adlandırılır) olan bir veri türüdür .

(kodlarım)


1
doğru, ama gereklilik aksi takdirde dikte olabilir
svarog

8
@svarog Görebildiğim tek şey kodun vasıfsız tasarımcı. Bool ve başka bir şey döndürmeniz gerekirse , onu bir sınıf, tuple veya liste veya belirli bir koda uyan başka bir şey yapın.
MatthewRock

evet döndürüyorsanız
svarog

Bence soru, Boole nesnesi değil, Boole ilkesiyle ilgili. Nesne bir değer değil.
Pieter B

1
Doğru veya yanlış dışında bir değer alabilirse, aynı zamanda bir boolean değildir. Bu isim verilen aptalca.
Yararsız

2

Sırf yapman gerektiği anlamına gelmediği için, JS'de herhangi bir nesneye özellikler ekleyebilirsin (Booleans dahil)

Bu nasıl kötü bir şey?

Bir yandan, bir Boole'ye daha fazla alakasız veri ekleyebilirsiniz (örneğin, örneğinize göre), başka bir geliştiricinin bekleyemeyeceği, çünkü neden orada olması gerekiyor ?! Bools sadece doğru ve yanlış.

Bunun bir karşıt noktası, boolean değeriyle başa çıkmanıza yardımcı olabilecek bazı yararlı özellikler eklemektir ( Java bunu yapar ).

Örneğin, boolean değerini bir dizgeye dönüştüren bir işlev dirty, değer değiştirildiğinde doğru olan bir bayrak, izleyiciler ve değer değiştiğinde ateşleyebilecek olay geri çağrıları vb. Ekleyebilirsiniz.

ancak döndürülen Boolean (Bool, JS'de birinci sınıf nesnedir) hangi formatların desteklendiğini belirleyen özelliklere sahiptir

Bir Boolean'da saklanması gereken bir şey değil, bir boolean dizisi veya içinde de boolean bulunan bir özellik kümesi kullanmak gibi bir şeye benziyor. Bence daha iyi bir yaklaşım, tüm formatları ve destek ayrıntılarını içeren bir nesneyi döndürmek olacak

{
    isSomethingSupported: true,
    isSomethingElseSupported: false,
    ....
}

1
Boole veya Boole (B harfiyle) mi demek istiyorsunuz?
Pieter B

1

JavaScript’te özel özelliklere sahip boolean'ler yapamazsınız. Aşağıdaki başarısız (en azından FF'de):

    var x = false;
    x.foo = "bar";
    console.log(x.foo);

Kullanabilir veya Boolean'dan miras alabilirsiniz, ancak Matthew Crumley'nin dediği gibi farklı sonuçlar verir. Booleantaşımaktadır türü Object . JS, bir ifadenin boolean değerine gereksinim duyduğunda , sonuç için her zaman ToBooleanolması gereken şartname işlevini kullanarak dönüştürür . Böylece değer değerlendirir ! Bunu bu örnekte doğrulayabilirsiniz: https://jsfiddle.net/md7abx5z/3/ .Objecttruenew Boolean(false)true

Modernizr için çalışmasının tek nedeni tesadüfidir. Yalnızca Booleankoşul doğru olduğunda bir nesne oluştururlar . Yanlışı değerlendirdiklerinde sıradan olurlar false. Bu yüzden işe yarıyor, çünkü Boolean nesneler sadece sonuç zaten doğru olduğunda ve asla yanlış olmadığında nesneleri döndürüyorlar.


1

Bağlamın değiştiğini anlıyorum, ancak örnek olarak JS'yi kullandığımı okuduğum orijinal soruyu cevaplamak istiyorum, ancak yalnızca JS ile sınırlı değil.

Bir boole özellik eklemek, özelliklerin değeri tutan değişkenle değil, doğru / yanlışla ilgisi varsa, bir sorun olmaz. Örneğin, birYesNoString yönteminin eklenmesi iyi olur, hasChildren değerine bir sayıOfChildren eklemek iyi olmaz, hem deMissed studentPassed soruları olmaz. Bir boole ekleyebileceğiniz çok fazla şey yok, çeşitli dize bildirimleri dışında, mantıklı olacağını düşündüğüm tek özellik originalExpression. Ancak buna ek olarak teoride mutlaka kötü bir fikir değildir.


0

Eğer koda bakarsam, bu gerçekten Boolean'a özel özellikler vermekle ilgili değil, farklı imzalara sahip dönüş yöntemleri olan bir yöntemle ilgili.

Yanlışsa, o zaman ilkel bir yanlış alırsınız ve eğer doğru ise javascript'te tanım olarak doğru yorumlanan bir nesneyi döndürür.

Bu nedenle, benim düşünceme göre, Boolean'a özel özellikler vermenin iyi bir fikir olup olmadığı değil, birden fazla iade imzası olan yöntemlere sahip olmanın iyi bir fikir olup olmadığı konusunda bence sorun olmamalıdır.


0

Verilen örnekte, desteklenen tüm video formatlarının bir dizisini döndüremez misiniz ?

  • Boş bir dizi aracı "Hiçbir video formatları sipariş araçlarında" hayır desteklenmez, " Video desteklenen".
  • Aksi takdirde, herhangi bir video formatı destekleniyorsa, açık bir şekilde genel olarak video desteklenir.

En azından, diziyi kullanmanın "özel boolean" lardan biraz daha az şaşırtıcı olduğunu söyleyebilirim.

Javascript'te boş bir dizi bile sahte sayılır , boş olmayan bir dizi kabadayı olsa da , biraz şansla dizilere geçebilir ve her şey Nope düzenlemeden önceki gibi çalışabilir, gerçeği hatırlayabileceğimi düşündüğüm için aptalca JavaScript içindeki nesnelerin sayısı: P


Boş bir dizi, if ifadesinde false olarak değerlendirilmez. if ([]) console.log ('yanlış değil'); Örneğin, Chrome'da 'yanlış değil' yazar. typeof [] === 'object', bu nedenle boş bir dizi sahte değildir. Referans için developer.mozilla.org/en-US/docs/Glossary/Truthy adresine bakın .
joshp

joshp ayy, haklısın benim hatam. Sabit
daniero

Yine de, her şeyin bir şey kanıtladığından emin değilim; ""typeof vardır "string"ama aslında sahte
daniero

1
Öte yandan, [].lengtheğer uzunluk ise 0, falsey , çok daha fazla yazma değildir ve bence if([])işe yarasa bile , niyetinden daha iyi bir niyet göstergesidir .
IllusiveBrian

@ daniero typeof [] === 'object' ile ilgili nokta, herhangi bir Object'in acımasız, hatta yeni Boole (false) olmasıdır. Bazı ilkel türler (örneğin, "" ve 0 sayısı) sahtedir, ancak bunlar tipe göre, Nesneler değildir. Hatırlamanın başka bir yolu. Bir şey kanıtlamakla ilgili değil. Kanıt, hangisinde tercih ederseniz, spesifikasyonda veya testlerdedir.
joshp
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.