Tüm argümanlarımı gerçek dünya kullanım örneklerine dayandığımı unutmayın. Gerçek, eksiksiz, ilginç, kullanışlı uygulamalarda kullanım örneği ile yedeklenemeyen karşı argümanlar geçersizdir. Herkesin sahip olduğu küçük "dil demoları" nı gördüm, prototiplerin ve dinamik yazmanın C # 'da olduğundan birkaç satır daha kısa bazı önemsiz küçük örnekleri nasıl yaptığını detaylandıran blog yayınlarını gördüm, ancak bunlar sadece ilgili değil
mikro-demolar ve oyuncaklar yerine gerçek kod yazarken karşılaştığınız sorunlara . İşte JS ile olan tutkularım:
a) Büyü 'bu'. Bu, bunun ne olduğu dışında. JavaScript, 'bu' değişken için her zaman uygun içeriği kaybetmeleri dışında sizi anonim işlevler kullanmaya iter, böylece her yerde "var _this = this" gibi aptal bir kodunuz olur ve bunu kullanırsınız. geri aramalarınızın veya diğer işlevlerin içinde. Bazı günler, yeniden adlandırılan 'this' kullanmayan yazmayı yönettiğim işlevlerin sayısının aslında olduğundan daha az olduğuna yemin ederim.
b) 1 + "1" - 1 = 10. Ayrıca, "1" + 0 = "10". Evet, bu aslında bir sayı olması beklenen verilerin bir JSON dosyasından başka bir uygulamadaki bir hata nedeniyle bir dize olarak yüklendiği ve sonuçların iyi olmadığı uygulamalarımız için hatalara neden oldu. Tüm yükleme kodumuz, her yere bir ton tür dönüşüm eklemek için güncellenmelidir. Bir sayı olmak için bir şeye ihtiyacım olduğunda gerçekten korkutuyorum kesinlikle bir sayı, bir dize veya bir nesne ya da null ya da başka bir şey olmasını istiyorum. Çoğu açıdan JavaScript'e çok benzeyen Lua, ekleme ve dize birleştirme için aynı operatörü kullanacak kadar geciktirilmeyerek bu sorunu düzeltti.
c) Varsayılan değişkenlere göre global. Değişken bildirimleri hakkında düşünmek zorunda olmadığınız için dinamik yazmanın sadece "daha kolay" olduğu argümanını alsanız bile, JavaScript her yerde yeni tanımlayıcıların önüne 'var' koymanızı sağlayarak bu argümanı pencereden dışarı atar. . Ve sonra unutursan seni sessizce vidalar.
d) Sınıflar yerine prototipler. Büyük uygulama mimarisindeki prototiplerin doğal yararsızlığı etrafında çalışmak için kendi sınıf sistemlerini takmayan çok az büyük ölçekli gerçek dünya JavaScript uygulaması vardır. Bu aynı uygulamalar, temel JavaScript türlerini genişletmek için minimum prototip kullanır ve yalnızca JS o kadar zayıf bir şekilde tasarlandığından, birlikte gelen iki ilginç yerleşik türün bile sahip olmasını beklediğiniz özelliklerin yarısından yoksundur.
e) Geçiş değeri türleri oluşturamama. Bu aslında C ++ / D dışında hemen hemen her dilde sık görülen bir sorundur. WebGL uygulamaları yazmak için JavaScript kullananların JavaScript için tüm doğrusal cebir kitaplıklarına bakın. 3D uygulamalarda neredeyse vektörleri skalerden daha sık kullanırsınız. "A = 1; b = a; b ++" ifadesinin hem a hem de b'yi 2'ye eşit hale getirmesi için uygulamanızdaki her tamsayı referansla iletilip iletilmediğini düşünün. Her üç bileşen vektörü tam bir tam nesnedir. Referans olarak geçilirler (aslında WebGL oyunumuzdaki hataların neredeyse yarısının kaynağı). Çok miktarda bulunurlar, yığınlara ayrılırlar ve çöp toplanırlar, bu da GC'ye yoğun bir baskı uygular, bu da basit WebGL oyunlarında bile GC duraklamalarına neden olabilir ve sonuçlanır, geliştirici, yeni vektörler oluşturmanın mantıklı olduğu tüm yerlerde yeni vektörler oluşturmaktan kaçınmak için gülünç derecede karmaşık halkalardan atlamazsa. Operatöre aşırı yükleme yapamazsınız, bu nedenle temel işlemleri yapmak için çok büyük ve çirkin ifadeleriniz olur. Tek tek bileşenlere erişim yavaştır. Nesneler yerel olarak paketlenmemiştir ve bu nedenle, şu anda hem V8 hem de SpiderMonkey'in optimize edicilerinin bokunu karıştıran bir Float32Array örnekleri olarak uygulamadığınız sürece bir köşe arabelleğine itmek inanılmaz derecede yavaştır. Referansla geçildiklerinden bahsetmiş miydim? Tek tek bileşenlere erişim yavaştır. Nesneler yerel olarak paketlenmemiştir ve bu nedenle, şu anda hem V8 hem de SpiderMonkey'in optimize edicilerinin bokunu karıştıran bir Float32Array örnekleri olarak uygulamadığınız sürece bir köşe arabelleğine itmek inanılmaz derecede yavaştır. Referansla geçildiklerinden bahsetmiş miydim? Tek tek bileşenlere erişim yavaştır. Nesneler yerel olarak paketlenmemiştir ve bu nedenle, şu anda hem V8 hem de SpiderMonkey'in optimize edicilerinin bokunu karıştıran bir Float32Array örnekleri olarak uygulamadığınız sürece bir köşe arabelleğine itmek inanılmaz derecede yavaştır. Referansla geçildiklerinden bahsetmiş miydim?
f) Yerleşik hiçbir işlev içermez veya işlevsellik gerektirmez. Cidden, hala. Üçüncü taraf kütüphaneleri var, ancak hemen hemen hepsinde bir çeşit hata var ya da başka bir şey değil, en azından Chrome'da kafa karıştırıcı bir önbellek sorunu, gerçek gelişimi popoda acı haline getiriyor.
g) Dinamik yazma. Evet, bu argümanı başlatmaya hazırım. En küçük Web uygulamalarını veya Web sayfalarını yazmayı en kısa sürede fark etmeye başlarsınız ve tek bir fare tıklamasından veya istek / yanıt döngüsünden daha uzun süre kalıcı olan verilerin olduğu büyük uygulamaları yazmaya başlarsınız: dizisini daha sonra işlemek ve eksik bir yöntemden veya üyeden daha sonra gerçek hatanın olduğu yerden tamamen farklı bir kod parçasında çökme elde etmek. Eğlenceli zamanlar. Evet, Java statik yazmanın kötü görünmesini sağlar. Hayır, Java / C # / C ++ statik yazmanın tek ve tek yolu değildir. Tür çıkarım, örtülü arayüz bağlama, vb tüm hatalar olmadan dinamik yazmanın tüm "başa çıkmak kolay ve çok sayıda tuş vuruşu değil" avantajları verir. En popüler ikinci Web dili olan ActionScript 3 aslında JS / ECMAScript ile aynı olmasına rağmen statik olarak yazılmıştır. Bir yana, Fedora masaüstümdeki Python uygulamalarından C / C ++ uygulamalarından daha fazla çökme alıyorum (aslında, masaüstü çökmemdeki C / C ++ uygulamalarının hiçbiri, şimdi düşündüğüm gibi). Eksik üye istisnaları == uygulamaları geliştirmek ve sürdürmek çok daha kolay, değil mi?
h) Hız. Evet, çok sayıda süper kötü eşek geliştiricisinin, JS'yi tek bir kolej Junior'ın birkaçında yazabileceği düşük dereceli bir C derleyicisinin neredeyse yarısı kadar hızlı hale getirmek için dil çalışma zamanlarına koyduğu gülünç derecede muazzam çabalar oldu. aydır. LuaJIT, temel dil sınırlamaları açısından JS ile aynı teknedir, ancak yine de her JavaScript uygulamasından daha iyisini yapmayı başarır. V8 ne tüm JS optimizasyonlar anlaşılması veya bu tür aslında olmayan insanlar doJS'nin şaşırtıcı şeyleri hızlı bir şekilde yapabileceğini iddia etmek gibi, ancak gerçek şu ki, tüm bu optimizasyonlar temelde "değişkenler için türleri anlamak için kodu analiz etmek için çok çok çalışın ve daha sonra biraz yavaş bir statik tip gibi derleyin dilin derleyicisi bunu yapardı. " Oh, ve izleme var, ancak daha sonra izleme, statik olarak yazılmış diller üzerinde de çalışır (ve oluşturulan makine kodunda tip korumalarına ihtiyaç duyulmaması nedeniyle daha iyi çalışır). Aslında bu vızıltı optimizasyonlarından sadece biri JS tarafından veya JS için icat edilmedi; çoğu araştırma JVM'lerinden (Java kötüdür!) veya klasik OOP dillerinden (prototipler harika!) alınmıştır.
i) IntelliSense bile mümkün değildir. Metin düzenleyicinizde foo.js satırının 187. satırında bulunan değişken üzerinde hangi yöntemlerin bulunduğunu görmek ister misiniz? Çok kötü. Nerede başlatıldığını anlayana kadar kod boyunca izlemeye devam edin, sonra da prototipinin üzerinde ne olduğunu bulmak için kodda iz sürün. Ve sonra arkadan prototipi dinamik olarak değiştiren bir kod olmadığını umuyoruz. Aslında, bir tarayıcıda çalıştırın ve kesme noktaları ayarlayın, çünkü değer hakkında yararlı bir şey bulmak için başka bir yol bulmak, JavaScript apologlarının JavaScript'in kolaylığı ve basitliğini yüceltmek için kullandıkları toy_web_app.html sitelerinden daha büyük herhangi bir kod tabanı için temel olarak imkansızdır. Bazı kod editörleri deneyin gerçekten iyi yapmak zor ve neredeyse tür gerçekten basit durumlar için başarılı, bazen kez sorta.
j) Avantaj yok. JavaScript, dinamik olarak yazılan diğer dillerle karşılaştırıldığında bile özel değildir. Lua, Python, Ruby, vb. Tarafından da yapılamayan ilginç bir şey yapamaz. JS uygulamalarının hiçbiri LuaJIT veya PyPy'den veya diğer dinamiklerin diğer gelişmiş JIT-ing uygulamalarından daha hızlı değildir. Diller. JS'nin diğer yaygın dillerle karşılaştırıldığında artı tarafı yoktur. Oh, bir eklenti olmadan bir Web tarayıcısında yerel olarak çalışması dışında. Dünyada bu kadar popüler olmasının tek nedeni budur. Aslında, olayın var olmasının tek nedeni. Eğer 10 yıl önce birisi sadece "heck, mevcut iyi tasarlanmış ve köklü bir dili tarayıcımıza bırakalım ve herkesin NetScape'in ortaya çıkardığı bu aptal küçük hackjob'u kullanmak yerine aynı şeyi yapmasını sağlayalım. , "Web bugün çok daha farklı (daha iyi) görünüyor. Chrome'un Python'u desteklenen bir dil olarak Chrome'a bırakması durumunda geleceği hayal edin. Veya şunu hayal edin: Google, C / C ++ 'ı Chrome'a desteklenen bir dil olarak bırakır (http://code.google.com/p/nativeclient/).