İlk fark şu şekilde özetlenebilir: sınıfın Eşgörünümüthis
anlamına gelir . Tanım anlamına gelir .prototype
Diyelim ki şu sınıfa sahibiz:
var Flight = function ( number ) { this.number = number; };
İşte burada this.number
sınıfın her örneğine bağlıyız ve bu mantıklıdır çünkü her Flight
birinin kendi uçuş numarası olmalıdır.
var flightOne = new Flight( "ABC" );
var flightTwo = new Flight( "XYZ" );
Buna karşılık, prototype
tüm örnekler tarafından erişilebilen tek bir özellik tanımlar.
Şimdi uçuş numarasını almak istiyorsak, aşağıdaki kod parçasını yazabiliriz ve tüm örneklerimiz bu yeni prototiplenmiş nesneye bir Referans alır .
Flight.prototype.getNumber = function () { return this.number; };
İkinci fark, JavaScript'in bir nesnenin özelliğini aramasıyla ilgilidir. Aradığın zamanObject.whatever
, JavaScript ana Object nesnesine (diğer her şeyin miras aldığı nesne) kadar gider ve bir eşleşme bulur bulmaz onu döndürür veya çağırır.
Ancak bu sadece prototip özellikleri için olur. Yüksek seviyelerde bir yeriniz varsathis.whatever
, JavaScript bunu bir eşleşme olarak kabul etmez ve aramaya devam eder.
Gerçekte nasıl olduğunu görelim.
İlk olarak [neredeyse] her şeyin JavaScript'teki Nesneler olduğunu unutmayın . Bunu dene:
typeof null
Şimdi bir içinde ne olduğunu görelim Object
(Büyük Harfe O
ve .
sonuna dikkat edin ). Google Chrome'un Geliştirici Araçları'na girdiğinizde, .
söz konusu nesnenin içindeki kullanılabilir özelliklerin bir listesini alırsınız.
Object.
Şimdi aynı şeyi yapın Function
:
Function.
name
Yöntemi fark edebilirsiniz . Sadece gidip kovun ve ne olacağını görelim:
Object.name
Function.name
Şimdi bir fonksiyon oluşturalım:
var myFunc = function () {};
Ve name
burada da yöntemi bulup bulamadığımızı görelim :
myFunc.name
Boş bir dize almalısın, ama sorun değil. Hata veya İstisna almamalısınız.
Şimdi o tanrıya bir şey ekleyelim Object
ve başka yerlerde de alıp almadığımızı görelim mi?
Object.prototype.test = "Okay!";
Ve işte gidiyorsunuz:
Object.prototype.test
Function.prototype.test
myFunc.prototype.test
Her durumda görmelisin "Okay!"
.
Her yöntemin avantajları ve dezavantajları ile ilgili olarak, prototip oluşturmayı bir şeyler yapmanın "daha verimli" bir yolu olarak düşünebilirsiniz, çünkü her nesnede tüm özelliği kopyalamak yerine her örnekte bir referans tutar. Öte yandan , sebebini gerçekten haklı gösterene kadar büyük bir hayır-hayır olan Sıkı Kuplaj örneğidir .this
bağlamla ilgili olduğu için oldukça karmaşıktır. İnternette ücretsiz olarak birçok iyi kaynak bulabilirsiniz.
Bununla birlikte, her iki yol da sadece dil araçlarıdır ve gerçekten size ve neyin daha iyi uyduğunu seçmek için çözmeye çalıştığınız soruna bağlıdır.
Bir sınıfın her örneğiyle alakalı olması için bir özelliğiniz olması gerekiyorsa, kullanın this
. Her örnekte aynı işlevi görmek için bir özelliğe sahip olmanız gerekiyorsa, kullanın prototype
.
Güncelleme
Örnek snippet'lerinizle ilgili olarak, birincisi Singleton örneğidir , bu nedenle this
nesne gövdesi içinde kullanmak mantıklıdır . Örneğinizi bu şekilde modüler hale getirerek de geliştirebilirsiniz (ve her zaman da kullanmanıza gerek yoktur this
).
/* Assuming it will run in a web browser */
(function (window) {
window.myApp = {
...
}
})( window );
/* And in other pages ... */
(function (myApp) {
myApp.Module = {
...
}
})( myApp );
/* And if you prefer Encapsulation */
(function (myApp) {
myApp.Module = {
"foo": "Foo",
"bar": function ( string ) {
return string;
},
return {
"foor": foo,
"bar": bar
}
}
})( myApp );
İkinci snippet'iniz pek mantıklı değil çünkü önce kullanıyorsunuz this
ve daha sonra onu hacklemeye çalışıyorsunuz prototype
, bu işe yaramıyor çünkü this
öncelikli prototype
. Bu koddan beklentilerinizin ne olduğundan ve nasıl çalıştığından emin değilim, ancak bunu yeniden düzenlemenizi tavsiye ederim.
Güncelleme
this
Öncelik almayı detaylandırmak için prototype
size bir örnek gösterebilir ve bunun nasıl açıklanabileceğini söyleyebilirim, ancak bunu destekleyecek harici bir kaynağım yok.
Örnek çok basit:
var myClass = function () { this.foo = "Foo"; };
myClass.prototype.foo = "nice try!";
myClass.prototype.bar = "Bar";
var obj = new myClass;
obj.foo; // Still contains "Foo" ...
obj.bar; // Contains "Bar" as expected
Açıklama, bildiğimiz gibi this
, bağlamla ilgilidir. Dolayısıyla bağlam hazır olana kadar ortaya çıkmayacak. Bağlam ne zaman hazır olur? Yeni örnek oluşturulurken! Şimdi gerisini tahmin etmelisin! Bu, bir prototype
tanım olmasına rağmen, this
öncelikli olmak için daha mantıklı olduğu anlamına gelir, çünkü her şey o anda yaratılan yeni örnekle ilgilidir.