Javascript'in perde sahnelerini anlamaya çalışıyorum ve nesnelerin, özellikle Nesne ve Fonksiyonun yaratılmasını ve aralarındaki ilişkiyi anlamaya sıkıştım.
Bu karmaşık, yanlış anlaşılması kolaydır ve birçok yeni başlayan Javascript kitabı yanlış anlıyor, bu yüzden okuduğunuz her şeye güvenmeyin.
1990'larda ve standardizasyon komitesinde Microsoft'un JS motorunun uygulayıcılarından biriydim ve bu yanıtı bir araya getirirken bir takım hatalar yaptım. (15 yılı aşkın süredir bu konuda çalışmadığım için affedilebilirim.) Bu zor şeyler. Ama prototip mirasını anladıktan sonra, her şey mantıklı.
Array, String vb.Gibi tüm yerleşik nesnelerin Object'den uzantı (devralınan) olduğunu okuduğumda, Object'in yaratılan ilk nesne olduğunu ve kalan nesnelerin kendisinden miras aldığını varsaydım.
Derse dayalı kalıtım hakkında bildiğiniz her şeyi atın. JS, prototip tabanlı miras kullanır.
Ardından, kafanızda "kalıtım" ın ne anlama geldiğini çok açık bir şekilde tanımladığınızdan emin olun. C # veya Java veya C ++ gibi OO dillerine alışkın olan insanlar, kalıtımın alt tipleme olduğunu düşünürler, ancak miras alt tipleme anlamına gelmez. Kalıtım, bir şeyin üyelerinin de başka bir şeyin üyeleri olduğu anlamına gelir . O değil mutlaka bu şeyler arasında bir alt-tiplemesi ilişki olduğunu demek! Tür teorisindeki pek çok yanlış anlama, insanların bir fark olduğunu fark etmemelerinin sonucudur.
Ancak, Nesnelerin yalnızca işlevler tarafından oluşturulabileceğini bilmeniz mantıklı değildir, ancak işlevler de İşlev nesnelerinden başka bir şey değildir.
Bu sadece yanlış. Bazı nesneler vardır değil arayarak yarattığı new Fbazı fonksiyon için F. Bazı nesneler JS çalışma zamanı tarafından hiçbir şey olmadan oluşturulur. Herhangi bir tavuk tarafından bırakılmayan yumurtalar var . Bunlar, başlangıçta çalışma zamanı tarafından oluşturuldu.
Kuralların ne olduğunu söyleyelim ve belki de bu yardımcı olacaktır.
- Her nesne örneğinin bir prototip nesnesi vardır.
- Bazı durumlarda bu prototip olabilir
null.
- Nesne örneğindeki bir üyeye erişirseniz ve nesnede bu üye yoksa, nesne prototipini savunur veya prototip boşsa durur.
prototypeBir nesnenin üyesi genellikle değil nesnenin prototip.
- Daha ziyade,
prototypebir fonksiyon nesnesinin F üyesi, tarafından yaratılan nesnenin prototipi haline gelecek olan nesnedir new F().
- Bazı uygulamalarda, örnekler
__proto__prototiplerini gerçekten veren bir üye alır. (Bu artık kullanımdan kaldırılmıştır. Buna güvenmeyin.)
- İşlev nesneleri
prototype, oluşturulduklarında atanan yepyeni bir varsayılan nesneye sahip olur.
- Bir fonksiyon nesnesinin prototipi elbette
Function.prototype.
Özetleyelim.
- Prototip
ObjectDİRFunction.prototype
Object.prototype nesne prototip nesnesidir.
- Prototip
Object.prototypeDİRnull
- Prototip
FunctionDİR Function.prototype- bu nadir durumlardan biridir Function.prototypeaslında bir prototipi Function!
Function.prototype işlev prototip nesnesidir.
- Prototip
Function.prototypeDİRObject.prototype
Farzedelim ki bir işlev Foo yapıyoruz.
- Prototip
FooDİR Function.prototype.
Foo.prototype Foo prototip nesnesidir.
- Prototip
Foo.prototypeDİR Object.prototype.
Varsayalım diyelim new Foo()
- Yeni nesnenin prototipi
Foo.prototype
Bunun mantıklı olduğundan emin olun. Hadi çizelim. Ovaller nesne örnekleridir. Kenarlar ya __proto__"prototipi" prototypeanlamına gelir ya da " prototypeözelliği " anlamına gelir .

Çalışma zamanının tek yapması gereken, tüm bu nesneleri oluşturmak ve çeşitli özelliklerini buna göre atamaktır. Eminim bunun nasıl yapılacağını görebilirsiniz.
Şimdi bilginizi test eden bir örneğe bakalım.
function Car(){ }
var honda = new Car();
print(honda instanceof Car);
print(honda.constructor == Car);
Bu ne yazdırıyor?
Ne instanceofdemek istiyorsun? honda instanceof Car" prototip zincirindeki Car.prototypeherhangi bir nesneye eşit hondami?"
Evet öyle. honda'ın prototipi Car.prototype, yani işimiz bitti. Bu doğru yazdırır.
İkincisi ne olacak?
honda.constructormevcut olmadığından prototipe danışıyoruz, yani Car.prototype. Ne zaman Car.prototypenesne otomatik bir özellik verildi oluşturulduğu constructoriçin eşit Carbu doğrudur, bu yüzden.
Şimdi buna ne dersiniz?
var Animal = new Object();
function Reptile(){ }
Reptile.prototype = Animal;
var lizard = new Reptile();
print(lizard instanceof Reptile);
print(lizard.constructor == Reptile);
Bu program ne yazdırıyor?
Yine, lizard instanceof Reptile" prototip zincirindeki Reptile.prototypeherhangi bir nesneye eşit lizardmi?"
Evet öyle. lizard'ın prototipi Reptile.prototype, yani işimiz bitti. Bu doğru yazdırır.
Şimdi ne olacak
print(lizard.constructor == Reptile);
Bunun da lizardinşa edildiğinden beri doğru yazdırdığını düşünebilirsiniz, new Reptileancak yanılıyorsunuz. Nedeni.
- Mu
lizardbir var constructormülkiyet? Hayır. Bu yüzden prototipe bakıyoruz.
- Prototipi
lizardolduğu Reptile.prototypeolan Animal.
- Mu
Animalbir var constructormülkiyet? Hayır. Bu yüzden prototipine bakıyoruz.
- Prototipi
Animalolan Object.prototypeve Object.prototype.constructorçalışma zamanı tarafından oluşturulan ve eşit olduğunu Object.
- Bu yanlış yazdırıyor.
Reptile.prototype.constructor = Reptile;Orada bir noktada söylemeliydik , ama hatırlamıyorduk!
Her şeyin sizin için anlamlı olduğundan emin olun. Hala kafa karıştırıcıysa bazı kutular ve oklar çizin.
Diğer son derece kafa karıştırıcı olan şey, eğer console.log(Function.prototype)bir işlev yazdırırsam, ancak console.log(Object.prototype)yazdırdığımda bir nesne yazdırır. Neden Function.prototypebir nesne olması gerektiği bir fonksiyon?
İşlev prototipi çağrıldığında geri dönen bir işlev olarak tanımlanır undefined. Bunu zaten biliyoruz Function.prototypeolduğu Functionişin garibi, prototip. Bu nedenle Function.prototype()yasaldır ve bunu yaptığınızda undefinedgeri dönersiniz. Yani bu bir işlev.
ObjectPrototip bu özelliği yoktur; çağrılabilir değil. Bu sadece bir nesne.
console.log(Function.prototype.constructor)o zaman tekrar bir işlevdir.
Function.prototype.constructoradildir Functionaçıkçası. Ve Functionbir işlevdir.
Şimdi bir şeyi kendiniz yaratmak için nasıl kullanabilirsiniz (Mind = blown).
Bunu fazla düşünüyorsun . Gereken tek şey, çalışma zamanının başladığında bir grup nesne oluşturmasıdır. Nesneler, dizeleri nesnelerle ilişkilendiren arama tablolarıdır. Çalışma zamanı başladığında, o yapması gereken atama başlatmak sonra bir kaç düzine boş nesneler oluşturmak ve olan prototype, __proto__, constructorve bu yüzden yaptıkları gerektiğini grafiği yapana kadar her nesnenin özelliklerine.
Size yukarıda verdiğim şemayı alıp constructorona kenarlar eklemeniz yararlı olacaktır. Bunun çok basit bir nesne grafiği olduğunu ve çalışma zamanının onu oluştururken sorun yaşamayacağını hızlı bir şekilde göreceksiniz.
İyi bir egzersiz kendiniz yapmak olacaktır. İşte, ben başlayacağım. Biz kullanacağız my__proto__anlamına "prototipi nesnesi" ve myprototype"prototipi özelliğini" demek.
var myobjectprototype = new Object();
var myfunctionprototype = new Object();
myfunctionprototype.my__proto__ = myobjectprototype;
var myobject = new Object();
myobject.myprototype = myobjectprototype;
Ve bunun gibi. Programın geri kalanını, "gerçek" Javascript yerleşik nesneleriyle aynı topolojiye sahip bir nesne kümesi oluşturmak için doldurabilir misiniz? Bunu yaparsanız, son derece kolay olduğunu göreceksiniz.
JavaScript'teki nesneler, yalnızca dizeleri diğer nesnelerle ilişkilendiren arama tablolarıdır . Bu kadar! Burada sihir yok. Kendinizi düğümlere bağlıyorsunuz, çünkü her nesnenin bir kurucu tarafından yaratılması gerektiği gibi, aslında var olmayan kısıtlamaları hayal ediyorsunuz.
İşlevler yalnızca ek bir özelliğe sahip nesnelerdir: çağrılacak. Bu yüzden küçük simülasyon programınızı gözden geçirin ve .mycallableher nesneye çağrılabilir olup olmadığını gösteren bir özellik ekleyin . Bu kadar basit.
Function.prototype, bunun bir işlev olabileceği ve iç alanlara sahip olabileceği anlamına gelir . Yani hayır, prototip işlevini yapısından geçerken yürütmezsiniz. Son olarak, Javascript'i yorumlayan bir motor olduğunu unutmayın, bu nedenle Nesne ve İşlev, Javascript'ten değil, motor içinde oluşturulabilir ve özel referans gibiFunction.prototypeveObject.prototypesadece motor tarafından özel bir şekilde yorumlanabilir.