Son zamanlarda bazı iyi, kötü ama çoğunlukla çirkin Java ile truding yaptığım ve Java ve Java devs vs JS hakkında genel olarak aşırı genelleştirmelerden oluşan yepyeni bir dolgunluğa sahip olduğum için bu soruya bir cevap eklemek istiyorum. JS, aslında faydalı gerçeğe belli belirsiz benzeyen bir şeye dayanıyor olabilir.
IDE'ler Var Ama Niçin Fazla Olmadığını Anlamak Yararlı Olabilir
Ben şimdi Webstorm'u deniyorum, kendimi Düğüm geliştirmeye çekiyordum ve gerçekten de satın almam yeterince kötü değil ama hala js dosyalarını Scite'de WS'den daha sık açma eğilimindeyim. Bunun nedeni, JS'de çok daha azıyla çok daha fazlasını yapabilmenizdir ancak UI çalışması anında geri bildirimde bulunduğundan, tarayıcı araçları (özellikle Chrome ve Firebug) gerçekten mükemmeldir ve (tarayıcı dışı bağlamlar için muhasebe) ) değiştirilmiş kodun tekrar çalıştırılması derleme adımına gerek kalmadan hızlı ve kolaydır.
Oldukça ikna olduğum bir diğer şey de, IDE'lerin JavaScript'te gerçekten göze alamayacağınız özensiz kodları etkinleştirerek temelde kendi taleplerini yaratmalarıdır. JS'de nasıl yönettiğimizi öğrenmek ister misiniz? Bir IDE'siz Java'da önemsiz olmayan bir şeyler yazmaya çalışarak başlamak ve bir IDE'siz hareket etmeden bu kodu sürdürmek / değiştirmek için yapmak ve düşünmek zorunda olduğunuz şeylere yakından dikkat etmek yardımcı olabilir. iletin. IMO, aynı şeyleri bir IDE olsun veya olmasın, bakımı yapılabilir kod yazmak için hala çok önemlidir. 4 yıllık bir programlama müfredatı yazmak zorunda kalsaydım, ilk iki yıl için bükülmüş alet ve bağımlılık alamaması için bir IDE'ye dokunmanıza izin vermezdi.
yapı
Karmaşık uygulamalarla uğraşan deneyimli JS dev'leri kodlarını yapılandırabilir ve yapabilir. Aslında, bizim için kodu okumak için IDE'lerin bulunmadığı erken bir tarihte daha iyi olma eğiliminde olduğumuz, ancak aynı zamanda güçlü biçimde ifade eden dillerin, düşünceli bir şekilde kodlamadığınız takdirde, tamamen sürdürülemez felaket kodlarını çok hızlı bir şekilde ifade edebildikleri için daha iyi olma eğiliminde olduğumuz bir şey.
Aslında son zamanlarda Java kod temeli- mizi anlamada oldukça dik bir öğrenme eğrisi yaşadım ve sonunda hiçbirinin uygun OOP olmadığını fark ettim. Sınıflar, çekirdeklerde veya DTO'larda veya statik alıcılar / ayarlayıcılarda yer alan küresel olarak mevcut verileri değiştiren gevşek bağlantılı yöntemlerden başka bir şey değildi. Temel olarak OOP'un değiştirmesi gereken eski canavardı. Bu yüzden temelde kod hakkında bakmak ve düşünmek durdu. Kısayol tuşlarını yeni öğrendim ve dağınıklıkları takip ettim ve her şey çok daha sorunsuz geçti. Zaten alışkanlıkta değilseniz, OOD hakkında çok daha fazla düşünün.
En üst düzeyde iyi yapılandırılmış bir JS uygulaması, karmaşık işlevlerden (örneğin, jQuery) ve birbiriyle etkileşime giren nesnelerden oluşma eğiliminde olacaktır. Herhangi bir dilde iyi yapılandırılmış, kolayca tutulan bir uygulamanın işaretinin, bir IDE veya Notepad ++ ile bakıp bakmamanın tamamen okunaklı olduğunu savunuyorum. Bağımlılık enjeksiyonu ve testte ilk TDD'yi aşırı derecede kritik bir şekilde eleştirmemin temel sebeplerinden biri budur.
Ve nihayet dersleri bırak. Prototip kalıtımını öğrenir. Miras almanız gerektiğinde uygulanması oldukça kolaydır. Bununla birlikte, kompozisyon yaklaşımlarının JS'de çok daha iyi çalışma eğilimi gösterdiğini düşünüyorum, ancak kişisel olarak hastalanmaya başladım ve herhangi bir dilde bir veya iki kalıtım seviyesinden daha fazla kalıtım gördüğümde EXTJS gece terörlerine maruz kaldım.
İlk Temel İlkeler
Diğer tüm iyi uygulamaların çıkarması gereken temel konulardan bahsediyorum: DRY, YAGNI, en az şaşkınlık ilkesi, sorunlu alanların temiz bir şekilde ayrılması, bir arayüze yazma ve okunaklı kod yazma benim kişisel çekirdeğim. Bu uygulamaların terk edilmesini savunan biraz daha karmaşık olan herhangi bir şey, herhangi bir dilde Kool Aid olarak düşünülmelidir, fakat özellikle bir sonraki adam için kafa karıştırıcı bir kod mirası bırakmanın çok kolay olduğu JavaScript gibi bir dilde olmalıdır. Örneğin gevşek kavrama, nesneler arasındaki etkileşimin nerede olduğunu bile söyleyemediğiniz kadar uzağa götürene kadar harika şeylerdir.
Dinamik Yazma Korkma
JavaScript'te çok fazla çekirdek türü yok. Çoğunlukla, dinamik döküm kuralları pratik ve açıktır, ancak bunları öğrenmek için ücret öder; böylece gereksiz akışlar ve anlamsız doğrulama rutinleri olmadan veri akışını yönetmeyi daha iyi öğrenebilirsiniz. Güven Bana. Sıkı tipler, performans ve derleme problemlerini tespit etmek için mükemmeldir ancak sizi hiçbir şeyden korumazlar.
JS İşlevleri ve Kapanışları Çıkmazını Öğrenin
JS'nin birinci sınıf işlevleri, tartışmasız temel olarak JS'nin "Müşteri Tarafı Web'e Ödülle Tek Dokunuşa Değer" dilini kazandırmasının temel nedenidir. Ve evet, aslında rekabet vardı. Aynı zamanda JS'nin merkezi bir özelliğidir. Onlarla nesneler inşa ediyoruz. Her şey fonksiyonlarla ilgilidir. Ve kullanışlı özelliklere sahipler. Parametreleri arguments anahtar sözcüğü ile inceleyebiliriz. Bunları geçici olarak başka nesnelerin yöntemleri olma bağlamında ekleyebilir ve ateşleyebiliriz. Ve olay odaklı yaklaşımları müstehcen şekilde uygulanması kolay hale getiriyor. Kısacası, JS'yi kaynağın karmaşıklığını azaltmada ve JS'nin (ancak çoğunlukla DOM API'sinin) farklı uygulamalarını kaynakta uyarlarken mutlak bir canavar yaptılar.
Kabul Etmeden Önce Kalıpları / Uygulamaları Yeniden Değerlendirin
Birinci sınıf fonksiyonlar ve dinamik tipler, JS'de tamamen karmaşık ve hantal olan daha karmaşık tasarım desenlerinin çoğunu oluşturur. Bununla birlikte, daha basit kalıpların bazıları, verilen JS'nin oldukça esnek yapısını uygulamak için inanılmaz derecede faydalı ve uygulaması kolaydır. Adaptörler ve dekoratörler özellikle kullanışlıdır ve oluşturdukları kullanıcı arayüzü öğeleri için etkinlik yöneticileri olarak da çalışan karmaşık kullanıcı arayüzü fabrikaları için singleton'ları faydalı buldum.
Dilin Liderini Takip Edin ve Daha Azıyla Daha Çok Şey Yapın
Java kafa honcho'larından birinin, herhangi bir yerde ayrıntıların tüm taraflar için kodun anlaşılmasını kolaylaştıran olumlu bir özellik olduğu iddiasını bir yere getirdiğine inanıyorum. Hogwash. Bu doğru olsaydı, hukukçu okumak daha kolay olurdu. Sadece yazar yazdıklarını daha kolay anlaşılır hale getirebilir ve bunu sadece kendini başkalarının yerine koyarken yapabilirsin. Öyleyse bu iki kuralı benimseyin. 1. Mümkün olduğunca doğrudan ve açık olun. 2. Şimdiden lanet noktaya gelin. Kazanç, temiz, özlü kodun, tetikleyiciden gerçek istenen eyleme ulaşmak için yirmi beş katı geçmeniz gereken bir şeyden daha kolay anlaşılması ve sürdürülmesidir. Bu tür şeyleri daha katı dillerde savunan çoğu model, aslında JavaScript'in sahip olmadığı sınırlamalar için geçici çözümlerdir.
Herşey Dövülebilir ve Bu Tamam
JS muhtemelen popüler kullanımdaki en az korumacı dillerden biridir. Onu kucakla. İyi çalışıyor. Örneğin, bir yapıcı işlevinde normal değişkenler bildirerek erişilemeyen kalıcı "özel" değişkenlere sahip nesneler yazabilirsiniz ve bunu sık sık yapıyorum. Ancak, kodumu veya kullanıcılarını "kendisinden" korumak zorunda değiller (çalışma zamanı boyunca sadece kendi sürümleriyle değiştirebiliyorlardı). Ama bunun yerine niyetin işaret etmesidir, çünkü varsayım, diğer adamın herhangi bir bağımlılığı çözmek istemeyecek kadar yetkin olduğu ve belki de doğrudan iyi bir sebepten doğrudan elde etmek istemediğinizi göreceğidir.
Boyut Sınırı Yok, Yalnızca Sorunlu Etki Alanları
Gördüğüm tüm Java kod tabanlarında karşılaştığım en büyük sorun, sınıf dosyalarının çoğalmasıdır. Her şeyden önce SOLID, OOP hakkında zaten bilmeniz gerekenlerin kafa karıştırıcı bir tekrarıdır. Bir sınıf, belirli bir dizi ilgili problemi ele almalıdır. Tek bir yöntemle ilgili bir sorun değil. Bu sadece eski eski func-spagetti C kodunu, sadece önyükleme yapmak için bütün anlamsız sınıf sözdizimlerinin eklenmesiyle alıyor. Boyut veya yöntem sınırı yoktur. Zaten uzun bir işleve veya sınıfa ya da yapıcıya bir şey eklemek mantıklıysa, mantıklı olur. JQuery'i al. Tek bir fonksiyondaki bütün bir kütüphane uzunluğu araç setidir ve bunda yanlış bir şey yoktur. JQuery'e hala ihtiyacımız var mı, makul bir tartışmaya bağlı, ancak tasarım açısından.
Eğer Java Hepiniz Biliyorsanız, C Tabanlı Olmayan Sözdizimi Olan Bir Şeyde Dabble
Python ile uğraşmaya başladığımda, çünkü Django hakkında duyduğum şeyi sevdim, sözdizimini dil tasarımından ayırmaya başladım. Sonuç olarak, Java ve C'yi, aynı sözdizimiyle farklı yaptıkları şeylerden ziyade, dil tasarım bölümlerinin toplamı olarak anlamak kolaylaştı. Güzel bir yan etki, tasarım açısından diğer dilleri ne kadar iyi anlarsanız, kontrast yoluyla en iyi bildiğiniz dillerin güçlü / zayıf yönlerini o kadar iyi anlarsınız.
Sonuç
Şimdi, bunların hepsini göz önünde bulundurarak, tüm problemlerinize değinelim:
- Bir işlevin giriş noktasını bulmanın hemen bir yolu yok (düz bir metin araması dışında, bu, daha sonra, nereden başladığınızı unuttuğunuzun üç veya üçünden sonra arama hiyerarşisini daha ileriye götüren yöntemler için daha sonra yapılan aramalarla sonuçlanabilir)
Chrome ve Firebug aslında arama izlemeye sahip. Ama aynı zamanda yapı ve noktaların özlü ve doğrudan tutulması konusundaki puanlarıma da bakın. Uygulamanızı birbiriyle etkileşime giren daha iyi kapsüllenmiş yapılar olarak ne kadar çok düşünürseniz, işler ters gittiğinde kimin suçu olduğunu bulmak o kadar kolay olur. Bunun Java için de geçerli olduğunu söyleyebilirim. Geleneksel OOP endişeleri için kusursuz bir şekilde hizmet verebilecek sınıf benzeri işlev yapıcılarımız var.
function ObjectConstructor(){
//No need for an init method.
//Just pass in params and do stuff inside for instantiation behavior
var privateAndPersistent = true;
//I like to take advantage of function hoisting for a nice concise interface listing
this.publicAndPointlessEncapsulationMurderingGetterSetter
= publicAndPointlessEncapsulationMurderingGetterSetter;
//Seriously though Java/C# folks, stop with the pointless getter/setters already
function publicAndPointlessEncapsulationMurderingGetterSetter(arg){
if(arg === undefined){
return privateAndPersistent;
}
privateAndPersistent = arg;
}
}
ObjectConstructor.staticLikeNonInstanceProperty = true;
var instance = new ObjectConstructor();//Convention is to capitalize constructors
Kodumda {}
, neredeyse hiçbir zaman nesne değişmezlerini yapısal uygulama bileşenleri olarak kullanmam çünkü içsel (özel) değişkenlere sahip olamazlar ve bunun yerine veri yapıları olarak kullanılmak üzere ayrılmayı tercih ederler. Bu, niyetin netliğini koruyan bir beklentinin belirlenmesine yardımcı olur. (Eğer eğrileri görürseniz, bu uygulama mimarisinin bir bileşeni değil, verileridir).
- Parametreler, bu parametrede hangi özelliklerin ve işlevlerin kullanılabilir olduğunu bilmenin hiçbir yolu olmadan, işlevlere iletilir (aslında programı çalıştırmak, işlevin çağrıldığı noktaya gitmek ve tüm özellikleri çıkarmak için console.logs kullanmak). mevcut)
Yine, modern tarayıcı araçlarına bakın. Ancak, programı tekrar çalıştırmak neden bu kadar sersem? Yeniden yükle, bir istemci tarafı web dev genellikle birkaç dakikada bir vurur, çünkü size kesinlikle yapacak hiçbir şey yapmaz. Yine bu, uygulama yapısının yardımcı olabileceği bir başka nokta ancak sözleşmeleri yürürlüğe sokmak için kendi validasyonunuzu uygulamanız gereken JS'nin aşağı yönlü bir taklididir (sadece kod tabanımın maruz kaldığı uç noktalarda yaptığım bir şey) kontrol etmeyin). IMO, tradeoff'un faydalarına değer.
- Anonim işlevlerin sıkça kullanılması, geri dönüşler olarak kullanılır; bu, sıklıkla hızlı bir şekilde dolaşamayacağınız kafa karıştırıcı kod yolları spagettiğine yol açar.
Evet önemsiz olmayan her şeyde kötü. Yapma bunu. İşlevlerinize çocuklar verin. Bir şeyleri izlemek de daha kolay. Aşağıdakiler ile aynı çizgide tanımlayabilir, değerlendirebilir (atamanız gerekir) ve basit bir önemsiz işlev atayabilirsiniz:
doSomethingWithCallback( (function callBack(){}) );
Artık, çağrıları takip ederken Chrome'un sizin için bir adı olacak. Önemsiz olmayan işlev için onu aramanın dışında tanımlarım. Ayrıca, bir değişkene atanan tek işlevli fonksiyonların hala adsız olduğunu unutmayın.
- Ve elbette, JSLint çalışma zamanından önce bazı hatalar yakalar, ancak bu bile doğrudan tarayıcınızda kodunuzun altında kırmızı dalgalı çizgiler olması kadar kullanışlı değildir.
Ben asla eşyalara dokunmam. Crockford topluluğa bazı iyi şeyler verdi, ancak JSLint çizgiyi stilistik tercihlere dönüştürüyor ve JavaScript'in bazı unsurlarını IMO'nun özellikle iyi bir nedenden ötürü kötü parçaları olduğunu öne sürüyor. RegEx ve negatif sınıfları ile ilgili bir şeyi kesinlikle * veya + ile yok sayın. Joker karakterler daha düşük performans gösteriyor ve tekrarlamayı {} ile kolayca sınırlandırabilirsiniz. Ayrıca, fonksiyon yapıcıları hakkında söylediği her şeyi görmezden gelin. Yeni anahtar kelime sizi rahatsız ediyorsa, bunları kolayca bir fabrika fonksiyonuna sartabilirsiniz. CSSLint (Crockford'ın değil) kötü tavsiye cephesinde bile daha kötü. Her zaman çok fazla konuşma yapan insanlara tuz ekin al. Bazen yemin ederim ki sadece otorite kurmaya ya da yeni malzemeler üretmeye çalışıyorlar.
Ve yine, bu çalışma zamanı kaygınızla öğrendiklerinizi öğrenmelisiniz. (Çok fazla Java / C # devs ile karşılaştığım yaygın bir durum.) Çalışma zamanında hataları görmek hala 2 yıl sonra sizi rahatsız ediyorsa, oturmanızı ve istenmeyen bir tarayıcıyı batıncaya kadar yeniden yüklemenizi istiyorum. derleme zamanı / çalışma zamanı bölünmesi yok (yine de görünmez olanı değil - JS şimdi JIT'de çalışıyor). Çalışma zamanında hataları keşfetmek sadece sorun değil, aldığınız her durma noktasındaki böcekleri yeniden yüklemek ve bu kadar ucuz ve kolay bir şekilde spam yüklemek için oldukça faydalıdır.
Ve şu Chrome geliştirme araçlarını kırmaya çalış. Doğrudan web kitinde yerleşikler. Chrome'da sağ tıklayın. Elemanı inceleyin. Sekmeleri keşfedin. Konsoldaki kodu çalışma süresi boyunca değiştirebilme yeteneğine sahip çok sayıda hata ayıklama gücü, en güçlü ancak daha az belirgin olan seçeneklerden biri. Test için de harika.
İlgili bir notta, hatalar arkadaşlarınızdır. Asla boş bir yakalama ifadesi yazma. JS biz değil hide yapmak veya hataları gömmek (ya da en azından biz olmamalı öksürük YUI / öksürük ). Onlara katılıyoruz. Daha az bir şey hata ayıklama ağrısına neden olur. Ve üretimdeki olası hataları gizlemek için bir catch deyimi yazarsanız, en azından hatayı sessizce kaydedin ve günlüğe nasıl erişileceğini belgeleyin.