DOM / yerleşik nesne prototiplerini genişletmek neden kötü bir fikir?


15

Yerleşik prototipleri genişletmenin neden JS geliştirici topluluğunda bu kadar ağır bir şekilde kısıtlandığına kesin bir cevap arıyorum. Prototip JS çerçevesini bir süredir kullanıyorum ve bana göre [1,2,3].each(doStuff)çok daha zarif görünüyor $.each([1,2,3], doStuff). Bunun "isim alanı kirliliği" yarattığını biliyorum, ama neden kötü bir şey olarak kabul edildiğini anlamıyorum. Ayrıca, yerleşik prototiplerin genişletilmesiyle ilgili herhangi bir gerçek performans düşüşü var mı? Teşekkürler!


1
Bir şey, for(var ... in ...)prototip fonksiyonları da geçtiğinden döngülerin dağılmasıdır.
pimvdb

4
"çok azgın", gerçekten mi ?! Tanrım, adamım:] iyi misin?
pixelbobby

Yanıtlar:


12

Prototip ile ilgili olarak nesneleri genişletmenin neden kötü bir fikir olduğunu oldukça iyi açıkladığını düşündüğüm bu makaleyi okumanızı öneriyorum .

Özetle:

Spesifikasyon eksikliği

"Prototip nesneler" in maruz kalması herhangi bir spesifikasyonun parçası değildir. [...] Uygulamanın DOM Düzey 2'ye tam olarak uyması için, bu genel Düğüm, Eleman, HTMLElement, vb. Nesnelerini göstermeye gerek yoktur.

Ana makine nesnelerinin kuralı yok

DOM nesneleri ana makine nesneleridir [...] Ana makine nesneleri, bu dahili yöntemleri uygulamaya bağlı herhangi bir davranışla uygulayabilir veya bir ana makine nesnesinin diğerlerine değil yalnızca bazı iç yöntemleri uygulaması olabilir.

[...] Dahili yöntemler davranışı uygulamaya bağlıdır. [...] Tanım olarak, öngörülemeyen ve tamamen düzensiz bir şekilde davranmasına izin verilen bir şeyle çalışıyorsunuz.

Çarpışma olasılığı

Bugün kullanımda olan çok sayıda ortam göz önüne alındığında, belirli mülklerin zaten bazı DOM'ların parçası olup olmadığını söylemek imkansız hale gelir. [...]

Her adlandırılmış form, prototip zinciri aracılığıyla devralınan özellikleri gölgelendirir. Form öğelerinde çarpışma ve beklenmedik hata olasılığı daha da yüksektir.

Bir tür ön ek stratejisi kullanmak sorunu hafifletebilir. Ama muhtemelen ekstra gürültü getirecektir.

Performans yükü

[...] IE 6, 7, Safari 2.x vb. gibi öğe uzantılarını desteklemeyen tarayıcılar manuel nesne uzantısı gerektirir. Sorun, manuel uzantının yavaş, rahatsız edici olması ve ölçeklendirilmemesidir.

[...] öğeleri genişletmeye başladığınızda, kütüphane API'sının büyük olasılıkla genişletilmiş öğeleri her yere döndürmesi gerekir. Sonuç olarak, $$ gibi sorgulama yöntemleri bir sorgudaki her bir öğeyi genişletebilir.

IE DOM bir karmaşa

Önceki bölümde gösterildiği gibi, manuel DOM uzantısı bir karışıklıktır. Ancak IE'de manuel DOM uzantısı daha da kötü [...]

Bonus: tarayıcı hataları


9

Diğer bir neden de kod okunabilirliği / sürdürülebilirliğidir. Başka bir geliştirici (özellikle bir acemi) kodumu okuyor ve görürse [0, 1, 2].foo(...), foo yönteminin ne olduğunu veya bunun için belgeleri / kaynağı nerede bulacağını bilmiyor olabilirler. Foo, prototype.js tarafından veya kullanılan başka bir kütüphane tarafından veya kodumun başka bir dosyadaki başka bir bölümü tarafından eklenen dile bir uzantı mıdır, yoksa bilmedikleri yerel bir JavaScript yöntemi midir? Bunun için avlanmalılar ve hemen bulamayabilirler (veya çatışmalar varsa doğru olanı bulamayabilirler).

JQuery yaklaşımıyla, görürseniz $.foo(...), foo yönteminin ad alanı, ne yaptığını bilmiyorsanız tanımını / belgelerini nerede bulacağını açıkça ortaya koyar.


Yöntemlerin nereden geldiğinin keşfedilebilirliği okuyucular için çok önemlidir. Her ne kadar gerçekten jQuery iyi bir örnek olduğunu düşünüyorum rağmen dolar işareti arama web kodu okuma içine atlamak ve zaten ne olduğunu bilmiyorum zorlu.
Simon Feltman

4

Temel sorun şudur: Prototipleri uyumsuz yollarla genişleten veya yaygın olarak adlandırılan yöntemleri farklı sonuçlar verecek şekilde genişleten ( for...inJavaScript'te belirli bir konudur ) iki aracınız varsa, bu da normal davranışlarını kırmak için?

Temel olarak, global değişkenleri yanlış kullandığınızda yaşadığınız sorunla aynıdır. Kendi başına, belki de kötü bir şey olmaz. Ancak, görünüşte ayrı olan iki kod parçası aniden birbirlerine bastığında sorun çıkarır (ve bu olduğunda hata ayıklamak bir acıdır).

Kesinlikle prototype.js oldukça iyi bilinir ve çoğu araç ne işe yaradığına bakar. Benzer şekilde, temel prototiplerin genişletilmesinin yapılması gereken doğru şey olduğuna eminim. Ancak, dikkatle yaklaşmak bir şey.


1

Bunun gerçekten hala bir sorun olup olmadığından emin değilim, ancak Internet Explorer'ın önceki sürümleriyle ilgili deneyimim, bazen belirli yerleşik türleri genişletmenin bile mümkün olmadığıdır.


1

Burada iki ayrı sorun var. Birincisi, yerleşik prototiplerin genel genişletilmesidir ve diğeri özellikle DOM prototiplerini genişletir. Yerleşik prototiplerin genişletilmesine karşı argümanlar:

  • Potansiyel çakışmalar: her ikisi de aynı prototipte aynı özelliği tanımlayan farklı kaynaklardan iki kod parçası
  • Yan etkiler: bir döngüde numaralandırılan uzantı yöntemlerini eklemek gibi genişletme Array.prototypeveya Object.prototypetakma efektleri olabilirfor...in

DOM prototiplerini genişletmeye gelince, yukarıdaki potansiyel çakışma argümanı hala geçerlidir. Ayrıca, DOM düğümleri ana bilgisayar nesneleridir ve bu nedenle yerel JavaScript nesnelerinin normal kurallarından hiçbirine tabi değildir. Esasen istediklerini yapabilirler ve mantıklı prototip nesneleri sağlamak ve hatta ekstra ("genişletme") özelliklerine izin vermek zorunda değildirler. IE özellikle tatbikatlarına bu hak, çeşitli DOM nesnelerde özellikleri hakkında çeşitli weirdnesses DOM IE 9 önce nesneleri için bir prototip sağlayan ve sahip (eğer elemanlar, hiçbir şeyin seti temin genellikle hoş atama özelliklerini konum rağmen document.expandoetmek false.)

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.