Her zaman özellikleri ve yöntemleri kontrol etmeden Javascript'te ördek yazmayı nasıl kullanırsınız?


11

Javascript ördek yazarak kullanır biliyorum ve ilk başta bu C # gibi güçlü yazılan dillere göre polimorfizmi kolay olacağını düşündüm. Ama şimdi argüman alan işlevlerim şu gibi şeylerle doludur:

if(myObj.hasSomeProperty())

veya

if(myObj.hasSomeMethod())

veya

if(isNumber(myParam))

vb.

Bu benim için gerçekten çirkin. Bir C # arka plan geliyor ve tanımlanmış arayüzleri çok daha iyi bulmak.

Statik olarak yazılan dillerde etkili olan stratejileri yanlış bir şekilde uygulamaya çalışıp çalışmadığımı merak ediyorum ve bunu javascript'te yapmanın daha iyi bir yolu var mı?

Sadece kontrol edemediğimi biliyorum, ancak javascript çalışma zamanı hatalarını takip etmek her zaman hatanın aslında kodda meydana geldiği yerde olmadığı için bir kabus olabilir.


2
Bence sadece dinamik olarak yazılmış bir dilin doğası üzerine kafa yoruyor olabilirsiniz. Zihninde derleme zamanı yerine çalışma zamanında çok fazla hata oluşacağına alışmak zorundasınız. Her argümanın sayıları giren her fonksiyonda bir sayı olup olmadığını kontrol etme gereğini hissediyorsanız, oldukça fazla bir yük haline gelebilir (yine de güvenlik en üst hedef olan bir lib gönderiyorsanız faydalı olabilir). Ölçekli herhangi bir şey için, sadece yanlış tipler geçilirse işlevlerin başarısız olmasına izin vermenin gerekli olduğunu düşünüyorum. Bunun yerine, testlerin oluşturulması üzerinde daha üretken bir odak olabilir.

Türlerin gerekli arabirim gereksinimlerine (örneğin, gerekli yöntemlere sahip olup olmadıklarını kontrol etmek) sağlamak için bu kontrolleri yapmanıza yardımcı olabilecek en merkezi ve yaygın olarak kullanılan işlevlerinizde (instabilite = 0 olanlarla) efferent / afferent kuplaj metriği sağlar). Bu oldukça küçük bir hedef olmalı. Tipik olarak kapsam dahilinde yalıtılan çok sayıda tek seferlik yerel işlev vardır - muhtemelen bu kadar kapsamlı bir çalışma zamanı denetimi setine ihtiyaç duymazlar. Çok fazla karmaşıklık birikmezler.

Komut Dosyası'na geçin. Hala ördekle yazılmış, ancak derleme zamanında birçok hatayı tespit etmek için statik yazmayı destekler.
CodesInChaos

2
Ördek yazmanın en büyük sorununa çarptınız: gücü zayıflığından kaynaklanıyor. Nesne yönelimli JavaScript yapmak istiyorsanız, sadece çalışma zamanı hatalarıyla yaşamak zorundasınız ve birim testlerinizi oluşturduktan hemen sonra bunları bulmasını umuyoruz :-(
Ross Patterson

@RossPatterson OPs sorunu ördek yazmayla değil dinamik yazmayla ilgilidir. TypeScript ve Go'nun ikisi de ördek türündedir, ancak OP sorunundan kaçının. Ördek yazmayla ilgili sorun farklıdır, yani ördek testini geçen ancak beklediğiniz sözleşmeyi yerine getirmeyen üyeleriniz olabilir.
CodesInChaos

Yanıtlar:


11

Her zaman özellikleri ve yöntemleri kontrol etmeden Javascript'te ördek yazmayı nasıl kullanırsınız?

Basit: her zaman özellikleri ve yöntemleri kontrol etmeyin.

Ruby'de aradığınız şeye "tavuk yazma" denir. Dinamik olarak ördek türünde bir dilde, arayanın size uygun bir nesneyi geçtiğine güvenirsiniz. Sözleşmenin tarafını onurlandırmak arayanın işi.

Javascript ördek yazarak kullanır biliyorum ve ilk başta bu C # gibi güçlü yazılan dillere göre polimorfizmi kolay olacağını düşündüm.

Burada birden çok dikey yazım eksenini karıştırıyorsunuz. Dört dikey yazma ekseni vardır:

  • Ne zaman : dinamik yazım (türler çalışma zamanına kadar bilinmiyor ve kontrol ediliyor) ve statik yazmaya (türler çalışma zamanından önce biliniyor ve kontrol ediliyor)
  • Nedir : ördek tipleme (tipler davranışa dayalı ), yapısal tipleme (tipler yapıya dayalı ) ve nominal tipleme (tipler isme dayalıdır )
  • Onları görebiliyor musun? açık yazarak (türlerin açık bir şekilde açıklanması gerekir) ve örtük yazarak (türler çıkarılır)
  • güçlü yazım ve zayıf yazım karşılaştırması - buna çekici bir başlık veya parantez içinde bir açıklama vermediğimi fark etmiş olabilirsiniz, çünkü her biri evrensel olarak kabul edilen tek bir kesin tanıma sahip olan yedi terimin aksine, bu iki terim birbirleriyle çelişen yaklaşık bir düzine yarı yaygın belirsiz tanımlara sahip olmak; ideal olarak tümüyle bu şartları kaçınmalısınız ve eğer gerekir bunları kullanmak, tam da önce onları tanımlamak

C # 'dan bahsettiğiniz için: çoğunlukla statik olarak yazılmıştır, ancak tür üzerinden dinamik yazmayı destekler dynamic, çoğunlukla nominal olarak yazılır, ancak anonim türler yapısal yazmayı kullanır ve sözdizimsel kalıpların (LINQ sorgu anlama sözdizimi gibi) her iki ördek olduğu iddia edilebilir. -tipli veya yapısal olarak yazılmış, çoğunlukla açıkça yazılır, ancak genel tür argümanları ve yerel değişkenler için örtük yazmayı destekler (yerel değişken durumu diğer dillere kıyasla oldukça garip olsa da, türü dışarıda bırakamazsınız, bunun yerine ona açık bir sözde tür vervar, başka bir deyişle, örtük bir tür istiyorsanız, açıkça söylemeniz gerekir). Bununla birlikte, C #'ın güçlü veya zayıf bir şekilde yazılıp yazılmadığı, hangi iki terimin tanımını kullandığınıza bağlıdır, ancak C # 'da, özellikle güvenli olmayan dizi kovaryansı nedeniyle çok sayıda çalışma zamanı türü hatası olabileceğini unutmayın.

Sadece kontrol edemediğimi biliyorum, ancak javascript çalışma zamanı hatalarını takip etmek her zaman hatanın aslında kodda meydana geldiği yerde olmadığı için bir kabus olabilir.

Hata ayıklama, öğrenmesi kolay bir beceri değildir. Bununla birlikte, hata ayıklamayı kolaylaştırmak için teknikler vardır, örneğin Saff Squeeze , Kent Beck tarafından açıklanan ve hata ayıklama için yeniden düzenleme kullanan bir tekniktir:

Hit 'em High, Hit' em Low :

Regresyon Testi ve Saf Sıkma

Kent Beck, Üç Nehir Enstitüsü

Özet: Bir arızayı etkin bir şekilde izole etmek için, sistem düzeyinde bir testle başlayın ve arızayı gösteren mümkün olan en küçük teste ulaşıncaya kadar aşamalı olarak satır içi ve budama yapın.


Bu hit em yüksek hit em düşük bağlantı benim için bir http 500 alır, "Sayfa artık kullanılabilir" insan odaklı mesaj olarak.
Joshp

Threeriversinstitute.org alan adı terk edilmiş gibi görünüyor.
Bart van Ingen Schenau

Ah, lanet olsun. Ve WayBack Makinesinde bile arşivlenmiyor .
Jörg W Mittag

Arayanın sözleşmenin tarafını nasıl onurlandırması gerekiyor? Görünüşe göre parametrelerin ne olması gerektiğini (kod içinde) iletmenin bir yolu yok. Her işlev fname (objParam, objParam, ...) biçimindedir. Bu, javascript gibi dillerin, kullanımı bildirmek için tamamen harici belgelere bağlı olduğu anlamına mı geliyor?
Lejyon

@Legion: dokümantasyon, iyi adlandırma, sağduyu, davranışsal özellikler olarak testler, kaynak kodunu okuma, adını siz koyun. Bunun aslında C # veya Java gibi daha zayıf tip sistemlerden çok farklı olmadığını unutmayın: Örneğin, dönüş değerinin anlamı IComparer<T>.Compare(T, T)türden değil, yalnızca belgelerden anlaşılır. Ve nerede java.util.Collections.binarySearch(java.util.List<T>)böyle diyor ki…
Jörg W Mittag

1

Sadece kontrol edemediğimi biliyorum, ancak javascript çalışma zamanı hatalarını takip etmek her zaman hatanın aslında kodda meydana geldiği yerde olmadığı için bir kabus olabilir.

Gerçekten, tipik uygulama kontrol etmek değildir. Ve evet, bu, gerçek sorundan başka bir yerde bildirilen javascript hataları alacağınız anlamına gelir. Fakat pratikte, bunun büyük bir sorun olduğunu düşünmüyorum.

Javascript ile çalışırken, sürekli yazdıklarımı test ediyorum. Çoğu kodda, editörümü her kaydettiğimde otomatik olarak çalışan birim testlerim var. Bir şey beklenmedik bir şekilde yanlış gittiğinde, hemen biliyorum. Hemen hemen her zaman hataya dokunduğum son şey olduğu için hata yapmış olabileceğim çok küçük bir kod alanım var.

Bir çalışma zamanı hatası aldığımda, en azından yığın izlemesi aldım ve tarayıcı içi bir hata durumunda, yığın izlemenin herhangi bir seviyesine gidip değişkenleri inceleyebildim. Kötü değerin nereden geldiğini izlemek ve böylece orijinal soruna kadar izlemek genellikle kolaydır.

Öncelikle statik olarak yazılan dillerde yazdığımda benim gibiyseniz, test etmeden önce daha büyük kod blokları yazdım ve nereden geldiği bir değeri izlemede pratik yapmadım. Javascript gibi bir dilde programlama farklıdır, farklı beceriler kullanmanız gerekir. Bunun gibi programlamanın daha zor göründüğünden şüpheleniyorum, çünkü bunlar C # gibi diğer dillerde çalışarak geliştirdiğiniz beceriler değil.

Bunu söyledikten sonra, açık tipler için söylenecek çok şey olduğunu düşünüyorum. Bunlar erken dokümantasyon ve hataları yakalamak için mükemmeldir. Gelecekte, javascript'e statik tip kontrolünü ekleyen Flow ve Typescript gibi şeylerin artan şekilde benimseneceğini göreceğiz.


0

Doğru şeyi yaptığınızı düşünüyorum, sadece gözünüze daha hoş gelecek stili bulmanız gerekiyor. İşte bazı fikirler:

  • Bunun yerine if(myObj.hasSomeProperty())kullanabilirsiniz if( myobj.prop !== undefined ). Bu, BTW yalnızca katı olmayan modda, katı modda kullanmanız gerekir if( typeof myobj.prop !== 'undefined' ).

  • Doğrulayıcıları ayırmak için bazı tür denetimlerini yükleyebilirsiniz. Bu, arayüzler olgunlaştıktan sonra, örneğin if( is_valid( myobject ))nerede başlarsa doğrulamayı atlayabilme avantajına is_validsahiptir if( !DEBUG ) return true;.

  • Bazen girişi kanonik bir formda klonlamak mantıklıdır, bu durumda çeşitli doğrulama hedeflerini klonlama işlevine / nesnesine toplayabilirsiniz. Xmaple için de yapıcı uygun merkezi bir yerde tüm çeşitli doğrulamaları çalıştırabilir.my_data = Data( myobj, otherstuff )Data

  • (Doğru geçiş ücretiyle) tür onayınızı daha zarif bir şeye dönüştürecek bir kütüphane kullanabilirsiniz. Bu rotayı uzun vadede kullanmasanız bile, sizi kendi tarzınıza sorunsuz bir şekilde ulaştırmak rahat olabilir. Bazı örnekler xtype.js , type-check , validator.js , vb.

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.