Prototipal kalıtımın klasiklere göre faydaları?


271

Sonunda tüm bu yıllar boyunca ayaklarımı sürüklemeyi bıraktım ve JavaScript'i "düzgün" öğrenmeye karar verdim. Diller tasarımının en temel unsurlarından biri mirasın uygulanmasıdır. Ruby'de deneyim sahibi olduğum için, kapanışları ve dinamik yazmayı gördüğüm için çok mutlu oldum; ama benim hayatım için miras için başka örnekleri kullanarak nesne örneklerinden ne gibi faydalar elde edilebileceğini anlayamıyorum.



Yanıtlar:


560

Bu cevabın 3 yıl geciktiğini biliyorum, ancak mevcut cevapların prototip mirasının klasik mirastan daha iyi olduğu hakkında yeterli bilgi sağlamadığını düşünüyorum .

İlk olarak JavaScript programcılarının prototip mirasını savunmak için belirttikleri en yaygın argümanları görelim (bu argümanları mevcut cevap havuzundan alıyorum):

  1. Basit.
  2. Güçlü.
  3. Daha küçük, daha az yedekli kod sağlar.
  4. Dinamik ve dolayısıyla dinamik diller için daha iyi.

Şimdi bu argümanların hepsi geçerli, ama kimse nedenini açıklamakla uğraşmadı. Bir çocuğa Matematik öğrenmenin önemli olduğunu söylemek gibi. Elbette öyle, ama çocuk kesinlikle umursamıyor; ve bunun önemli olduğunu söyleyerek Maths gibi bir çocuğu yapamazsınız.

Prototip palet miras sorun JavaScript açısından açıklanması olduğunu düşünüyorum. JavaScript'i seviyorum, ancak JavaScript'teki prototip kalıtım yanlış. Klasik kalıtımdan farklı olarak iki prototip kalıtım paterni vardır:

  1. Prototip paletinin prototip modeli.
  2. Prototip paletinin yapıcı modeli.

Ne yazık ki JavaScript prototypal mirasının yapıcı modelini kullanıyor. Çünkü JavaScript oluşturulduğunda, Brendan Eich (JS'nin yaratıcısı) Java'ya (klasik mirasa sahip) benzemesini istedi:

Ve Java'yı küçük bir kardeş olarak itiyorduk, o sırada Visual Basic gibi tamamlayıcı bir dil Microsoft'un dil ailelerinde C ++ içindi.

Bu kötü çünkü insanlar JavaScript'te kurucu kullandıklarında diğer kuruculardan miras kalan kurucuları düşünüyorlar. Bu yanlış. Prototip paletinde miras nesneleri diğer nesnelerden miras alır. Yapıcılar asla resme girmezler. Çoğu insanın kafasını karıştıran şey budur.

Klasik kalıtıma sahip Java gibi dillerden insanlar daha da karışıyor çünkü kurucular sınıflara benzese de sınıf gibi davranmıyorlar. As Douglas Crockford belirtti:

Bu dolaylı anlatım, dilin klasik olarak eğitilmiş programcılara daha tanıdık gelmesini sağlamaya yönelikti, ancak Java programcılarının JavaScript'e sahip olduğu çok düşük görüşten görebildiğimiz gibi bunu başaramadı. JavaScript'in yapıcı modeli klasik kalabalığa hitap etmedi. Ayrıca JavaScript'in gerçek prototip yapısını da gizledi. Sonuç olarak, dili etkili bir şekilde kullanmayı bilen çok az programcı vardır.

İşte aldın. Atın ağzından.

Gerçek Prototip Paleti

Prototip palet miras tamamen nesnelerle ilgilidir. Nesneler özellikleri diğer nesnelerden devralır. Hepsi bu kadar. Prototip paletini kullanarak nesne oluşturmanın iki yolu vardır:

  1. Yepyeni bir nesne oluşturun.
  2. Mevcut bir nesneyi klonlayın ve genişletin.

Not: JavaScript, bir nesneyi klonlamak için iki yol sunar - temsilci seçme ve birleştirme . Bundan sonra, yalnızca delegasyon yoluyla mirasa atıfta bulunmak için "klon" kelimesini ve sadece birleştirme yoluyla mirasa atıfta bulunmak için "kopya" kelimesini kullanacağım.

Bu kadar konuşma yeter. Hadi bazı örneklere bakalım. Diyelim ki bir yarıçap çemberi var 5:

var circle = {
    radius: 5
};

Dairenin alanını ve çevresini yarıçapından hesaplayabiliriz:

circle.area = function () {
    var radius = this.radius;
    return Math.PI * radius * radius;
};

circle.circumference = function () {
    return 2 * Math.PI * this.radius;
};

Şimdi başka bir yarıçap dairesi oluşturmak istiyorum 10. Bunu yapmanın bir yolu:

var circle2 = {
    radius: 10,
    area: circle.area,
    circumference: circle.circumference
};

Ancak JavaScript daha iyi bir yol sağlar - temsilci seçme . Object.createFonksiyon Bunu yapmak için kullanılır:

var circle2 = Object.create(circle);
circle2.radius = 10;

Bu kadar. JavaScript'te prototip palet miras yaptınız. Basit değil miydi? Bir nesneyi alırsınız, klonlar, ihtiyacınız olanı değiştirirsiniz ve hey presto - kendinize yepyeni bir nesne elde edersiniz.

Şimdi, "Bu nasıl basit? Her yeni bir çevre oluşturmak istediğimde, klonlayıp circleelle bir yarıçap atamam gerekiyor" diye sorabilirsiniz . Çözüm, ağır kaldırma işlemini sizin için yapmak için bir işlev kullanmaktır:

function createCircle(radius) {
    var newCircle = Object.create(circle);
    newCircle.radius = radius;
    return newCircle;
}

var circle2 = createCircle(10);

Aslında tüm bunları aşağıdaki gibi tek bir nesne değişmezinde birleştirebilirsiniz:

var circle = {
    radius: 5,
    create: function (radius) {
        var circle = Object.create(this);
        circle.radius = radius;
        return circle;
    },
    area: function () {
        var radius = this.radius;
        return Math.PI * radius * radius;
    },
    circumference: function () {
        return 2 * Math.PI * this.radius;
    }
};

var circle2 = circle.create(10);

JavaScript'te Prototypal Kalıtım

Yukarıdaki programda, createfonksiyonun bir klonu oluşturduğunu fark ederseniz circle, radiusona bir yeni atar ve ardından döndürür. Bir kurucu JavaScript'te tam olarak bunu yapar:

function Circle(radius) {
    this.radius = radius;
}

Circle.prototype.area = function () {
    var radius = this.radius;
    return Math.PI * radius * radius;
};

Circle.prototype.circumference = function () {         
    return 2 * Math.PI * this.radius;
};

var circle = new Circle(5);
var circle2 = new Circle(10);

JavaScript'teki yapıcı modeli, ters çevrilmiş prototip kalıptır. Bir nesne oluşturmak yerine bir kurucu oluşturursunuz. newKelime bağlanan thisbir klonuna kurucu içinde işaretçi prototypeyapıcı.

Kafa karıştırıcı geliyor mu? Çünkü JavaScript'teki yapıcı deseni gereksiz yere işleri karmaşık hale getirir. Çoğu programcının anlaması zor olan budur.

Diğer nesnelerden miras kalan nesneleri düşünmek yerine, diğer kuruculardan miras kalan yapıcıları düşünürler ve sonra tamamen karışırlar.

JavaScript'teki yapıcı modelinden kaçınılması gereken başka birçok neden daha var. Bunları blog yayınımda okuyabilirsiniz: Constructors vs Prototypes


Peki prototip mirasın klasik mirastan faydaları nelerdir? En yaygın argümanları tekrar gözden geçirelim ve nedenini açıklayalım .

1. Prototypal Kalıtım Basit

CMS cevabında şöyle diyor:

Bence prototip kalıtımın en büyük yararı basitliğidir.

Az önce ne yaptığımızı düşünelim. circleYarıçapı olan bir nesne yarattık 5. Sonra klonladık ve klonun yarıçapını verdik 10.

Bu nedenle prototip mirasın işe yaraması için sadece iki şeye ihtiyacımız var:

  1. Yeni bir nesne oluşturmanın bir yolu (örneğin, nesne değişmez değerleri).
  2. Mevcut bir nesneyi genişletmenin bir yolu (örn. Object.create).

Buna karşılık klasik kalıtım çok daha karmaşıktır. Klasik mirasta:

  1. Sınıflar.
  2. Nesne.
  3. Arabirimler.
  4. Soyut dersler.
  5. Final Sınıfları.
  6. Sanal Temel Sınıflar.
  7. Yapıcılar.
  8. Yıkıcılar.

Kaptın bu işi. Mesele şu ki prototip mirasın anlaşılması daha kolay, uygulanması daha kolay ve akıl yürütmesi daha kolay.

Steve Yegge'nin klasik blog yazısı " N00b'nin Portresi " ne koyduğu gibi :

Meta veriler, başka bir şeyin herhangi bir açıklaması veya modelidir. Kodunuzdaki yorumlar yalnızca hesaplamanın doğal bir açıklamasıdır. Meta veri meta verilerini yapan şey, kesinlikle gerekli olmamasıdır. Bazı soyağacı evrakları olan bir köpeğim varsa ve evrakları kaybedersem, hala geçerli bir köpeğim var.

Aynı anlamda sınıflar sadece meta verilerdir. Kalıtım için sınıflara kesinlikle gerek yoktur. Ancak bazı insanlar (genellikle n00bs) dersleri çalışmak için daha rahat bulurlar. Onlara yanlış bir güvenlik duygusu verir.

Ayrıca, statik türlerin sadece meta veri olduğunu da biliyoruz. İki tür okuyucuya yönelik özel bir yorumdur: programcılar ve derleyiciler. Statik türler, muhtemelen her iki okuyucu grubunun da programın amacını anlamasına yardımcı olmak için hesaplama hakkında bir hikaye anlatır. Ancak statik türler çalışma zamanında atılabilir, çünkü sonunda sadece stilize yorumlar. Soy ağacı evrakları gibidirler: köpekleri hakkında belirli bir güvensiz kişilik tipini daha mutlu edebilir, ancak köpek kesinlikle umursamaz.

Daha önce de belirttiğim gibi, sınıflar insanlara sahte bir güvenlik duygusu verir. Örneğin NullPointerException, kodunuz mükemmel okunabilir olsa bile Java'da çok fazla s alırsınız . Klasik kalıtımın genellikle programlama yoluna girdiğini düşünüyorum, ama belki de sadece Java. Python inanılmaz bir klasik kalıtım sistemine sahiptir.

2. Prototypal Kalıtım Güçlüdür

Klasik bir arka plandan gelen çoğu programcı, klasik kalıtımın prototip kalıtımdan daha güçlü olduğunu savunur çünkü:

  1. Özel değişkenler.
  2. Çoklu kalıtım.

Bu iddia yanlıştır. JavaScript'in özel değişkenleri kapanışlarla desteklediğini zaten biliyoruz , ancak çoklu kalıtım ne olacak? JavaScript'teki nesnelerin yalnızca bir prototipi vardır.

Gerçek şu ki prototip kalıtım birden fazla prototipten miras almayı destekler. Prototip palet devri, bir nesnenin başka bir nesneden miras alınması anlamına gelir. Aslında prototip mirasını uygulamanın iki yolu vardır :

  1. Yetki Devri veya Diferansiyel Miras
  2. Klonlama veya Birleştirici Kalıtım

Evet JavaScript yalnızca nesnelerin başka bir nesneye yetki vermesine izin verir. Ancak, rastgele sayıda nesnenin özelliklerini kopyalamanızı sağlar. Örneğin _.extend, sadece bunu yapar.

Elbette birçok programcı bu doğrudur miras olarak düşünmüyoruz nedeniyle instanceofve isPrototypeOfbaşka türlü söylemek. Ancak bu, bir prototipten birleştirme yoluyla devralınan her nesne üzerinde bir dizi prototip saklanarak kolayca giderilebilir:

function copyOf(object, prototype) {
    var prototypes = object.prototypes;
    var prototypeOf = Object.isPrototypeOf;
    return prototypes.indexOf(prototype) >= 0 ||
        prototypes.some(prototypeOf, prototype);
}

Bu nedenle prototip kalıtım, klasik kalıtım kadar güçlüdür. Aslında, klasik kalıtımdan çok daha güçlüdür, çünkü prototip mirasında, farklı prototiplerden hangi özellikleri kopyalayacağınızı ve hangi özellikleri atlayacağınızı seçebilirsiniz.

Klasik kalıtımda, miras almak istediğiniz özellikleri seçmek imkansızdır (veya en azından çok zordur). Elmas problemini çözmek için sanal temel sınıfları ve arayüzleri kullanıyorlar .

Ancak JavaScript'te büyük olasılıkla elmas sorununu asla duymayacaksınız, çünkü hangi özellikleri devralmak istediğinizi ve hangi prototiplerden kontrol edebileceğinizi tam olarak kontrol edebilirsiniz.

3. Prototip Paleti Daha Az Gereksizdir

Bu noktayı açıklamak biraz daha zordur çünkü klasik kalıtım zorunlu olarak daha fazla gereksiz koda yol açmaz. Aslında miras, ister klasik ister prototip, koddaki fazlalığı azaltmak için kullanılır.

Bir argüman, klasik kalıtımı olan çoğu programlama dilinin statik olarak yazılması ve kullanıcının türleri açıkça belirtmesini gerektirmesidir (örtülü statik yazmaya sahip Haskell'den farklı olarak). Dolayısıyla bu daha ayrıntılı koda yol açar.

Java bu davranış için kötü şöhretlidir. Bob Nystrom'un blog yazısında Pratt Parsers hakkındaki aşağıdaki fıkradan bahsettiğini açıkça hatırlıyorum :

Burada Java'nın "lütfen dört katına imzalayın" bürokrasi seviyesini sevmelisiniz.

Yine, bunun sadece Java'nın çok fazla emmesi nedeniyle olduğunu düşünüyorum.

Geçerli bir argüman klasik mirası olan tüm dillerin çoklu mirası desteklemediğidir. Yine Java akla geliyor. Evet Java'nın arayüzleri var, ama bu yeterli değil. Bazen gerçekten birden fazla mirasa ihtiyacınız vardır.

Prototipal kalıtım çoklu kalıtıma izin verdiğinden, çoklu kalıtım gerektiren kod, klasik kalıtım olan ancak çoklu kalıtım olmayan bir dilde değil, prototip kalıtım kullanılarak yazıldığında daha az gereksizdir.

4. Prototip Paleti Dinamiktir

Prototip paletinin en önemli avantajlarından biri, prototiplere oluşturulduktan sonra yeni özellikler ekleyebilmenizdir. Bu, bir prototipe, o prototip için temsilci olan tüm nesneler için otomatik olarak kullanılabilir hale getirilecek yeni yöntemler eklemenizi sağlar.

Klasik mirasta bu mümkün değildir, çünkü bir sınıf oluşturulduktan sonra onu çalışma zamanında değiştiremezsiniz. Bu muhtemelen prototipal kalıtımın klasik kalıtımdan en büyük avantajı ve en üstte olması gerekiyordu. Ancak ben sonuna kadar en iyi tasarruf seviyorum.

Sonuç

Prototip palet mirası önemlidir. JavaScript programcılarını prototip mirasının yapıcı modelini neden prototip mirasının prototip deseni lehine terk edecekleri konusunda eğitmek önemlidir.

JavaScript'i doğru bir şekilde öğretmeye başlamamız gerekiyor ve bu da yeni programcılara yapıcı modeli yerine prototip desenini kullanarak nasıl kod yazacaklarını göstermek anlamına geliyor.

Prototip paletini kullanarak prototip kalıtımını açıklamak daha kolay olmakla kalmaz, aynı zamanda daha iyi programcılar yapar.

Bu yanıtı beğendiyseniz , " Neden Prototypal Miras Önemlidir " konulu blog yayınımı da okumalısınız . Güven bana, hayal kırıklığına uğramayacaksınız.


33
Nereden geldiğinizi anlıyorum ve prototip mirasının çok faydalı olduğunu kabul etsem de, bence "prototip mirası klasik mirastan daha iyidir" varsayımını zaten başarısızlığa mahkumdur. Size bir bakış açısı kazandırmak için, jTypes kütüphanem JavaScript için klasik bir miras kütüphanesidir. Bunu yapmak için zaman alan bir adam olarak, hala burada oturup prototip mirasının harika ve çok yararlı olduğunu söyleyeceğim. Ancak bir programcının sahip olduğu birçok araç arasında sadece bir araçtır. Prototipal kalıtımın hala birçok dezavantajı vardır.
redline

7
Söylediklerine tamamen katılıyorum. Çok fazla programcının klasik kalıtım eksikliği nedeniyle JavaScript'i reddettiğini veya basit ve dilsiz bir dil olarak kınadığını hissediyorum. Aslında son derece güçlü bir kavram, katılıyorum ve birçok programcı bunu kabul etmeli ve öğrenmelidir. Bununla birlikte, JavaScript'te, argümanlarına gerçekten hiç dayanmadıkları zaman, hep birlikte JavaScript'te olmak için herhangi bir klasik kalıtım biçimine karşı çıkan önemli sayıda geliştirici olduğunu hissediyorum. Her ikisi de kendi başlarına eşit derecede güçlü ve aynı derecede faydalı.
redline

9
Fikriniz bu, ancak katılmamaya devam edeceğim ve bence CoffeeScript ve TypeScript gibi şeylerin artan popülaritesi, uygun olduğunda bu işlevselliği kullanmak isteyen büyük bir geliştirici topluluğu olduğunu gösteriyor. Söylediğiniz gibi, ES6 sözdizimsel şeker ekler, ancak yine de jTypes'in genişliğini sunmaz. Bir yan notta, aşağı oyunuzdan sorumlu olan ben değilim. Sana katılmıyorum, bunun kötü bir cevabın olduğunu düşünmüyorum. Çok titizdin.
redline

25
Kelime klonunu çok kullanıyorsunuz, bu sadece yanlış. Object.createbelirtilen prototiple yeni nesne oluşturuyor. Kelimeleri seçmeniz, prototipin klonlandığı izlenimini verir.
Pavel Horal

7
@Aadit: Gerçekten bu kadar savunmacı olmaya gerek yok. Cevabınız çok ayrıntılı ve oy hak ediyor. "Bağlantılı" ifadesinin "klon" için bir yedek yerine geçmesi gerektiğini söylemiyordum, ancak "klon" terimini kendi tanımınızı ileri sürsünüz, ister bir nesne ile miras aldığı prototip arasındaki bağlantıyı daha uygun bir şekilde açıklıyor. " ya da değil. Değiştir ya da değiştirme, tamamen senin seçimin.
Andy E

42

Soruya satır içi cevap vermeme izin verin.

Prototip mirası aşağıdaki erdemlere sahiptir:

  1. Dinamik diller için daha uygundur, çünkü miras bulunduğu ortam kadar dinamiktir. .
  2. Bir prototipleme nesne şemasını uygulamak klasik sınıf / nesne ikilem şemalarından daha kolaydır.
  3. "Metaclasses" (asla sevmediğim metaclass ... üzgünüm!) Veya "özdeğerler" veya benzeri gibi nesne modeli çevresindeki karmaşık keskin kenarlara olan ihtiyacı ortadan kaldırır.

Bununla birlikte, aşağıdaki dezavantajlara sahiptir:

  1. Bir prototip dilini kontrol etmek imkansız değil, ama çok, çok zor. Prototip dillerin çoğu "tip kontrolü" saf çalışma zamanı "ördek yazma" tarzı kontrollerdir. Bu, tüm ortamlar için uygun değildir.
  2. Statik (veya çoğu zaman dinamik bile) analizlerle yöntem dağıtımını optimize etmek gibi şeyler yapmak da zordur. Bu olabilir (ı stres: edebilir ) çok kolay çok verimsiz olabilir.
  3. Benzer şekilde, nesne oluşturma, bir prototipleme dilinde, daha geleneksel bir sınıf / nesne ikilik şemasında olduğundan çok daha yavaş olabilir (ve genellikle de).

Yukarıdaki satırlar arasında okuyabilir ve geleneksel sınıf / nesne şemalarının ilgili avantajlarını ve dezavantajlarını ortaya çıkarabilirsiniz. Tabii ki, her alanda daha fazlası var, bu yüzden geri kalanını cevaplayan diğer insanlara bırakıyorum.


1
Hey bak, fanboy olmayan özlü bir cevap. Gerçekten bu sorunun en iyi cevabı olsaydı.
siliconrockstar

Kod çalışırken, her bölüm için farklı kod parçaları oluşturarak kodu derleyebilen Dinamik Tam Zamanında derleyicilerimiz var. JavaScript, prototipleri kullansanız bile klasik sınıfları kullanan Ruby veya Python'dan daha hızlıdır çünkü onu optimize etmek için çok fazla çalışma yapılmıştır.
aoeu256

28

IMO prototip paletinin en büyük yararı basitliğidir.

Dilin prototip doğası, klasik olarak eğitilmiş insanları karıştırabilir , ancak aslında bunun gerçekten basit ve güçlü bir kavram, farklı bir miras olduğu ortaya çıkıyor .

Sınıflandırma yapmanız gerekmez , kodunuz daha küçük, daha az yedeklidir, nesneler diğer daha genel nesnelerden miras alınır.

Prototip olarak düşünürseniz , yakında derslere ihtiyacınız olmadığını fark edeceksiniz ...

Prototypal mirası yakın gelecekte çok daha popüler olacak, ECMAScript 5. Baskı belirtimi Object.create, başka birinden gerçekten basit bir şekilde miras alan yeni bir nesne örneği oluşturmanıza izin veren yöntemi tanıttı :

var obj = Object.create(baseInstance);

Standardın bu yeni sürümü tüm tarayıcı satıcıları tarafından uygulanmaktadır ve bence daha saf prototip palet mirasını görmeye başlayacağız ...


11
"kodunuz daha küçük, daha az yedekli ...", neden? "Diferansiyel kalıtım" için wikipedia bağlantısına bir göz attım ve bu iddiaları destekleyen hiçbir şey yok. Klasik kalıtım neden daha büyük, daha fazla kodla sonuçlanır?
Noel Abrahams

4
Kesinlikle Noel ile hemfikirim. Prototypal mirası, bir işi yapmanın sadece bir yoludur, ancak bu onu doğru şekilde yapmaz. Farklı araçlar farklı işler için farklı şekillerde çalışacaktır. Prototip palet mirasının yeri vardır. Son derece güçlü ve basit bir kavramdır. Bununla birlikte, gerçek kapsülleme ve polimorfizm için destek eksikliği JavaScript'i önemli bir dezavantaja sokmaktadır. Bu metodolojiler JavaScript'inkinden çok daha uzundur ve ilkelerinde sağlamdır. Bu yüzden prototipin "daha iyi" olduğunu düşünmek, tamamen yanlış zihniyettir.
redline

1
Prototip tabanlı kalıtım kullanarak sınıf tabanlı kalıtımı simüle edebilirsiniz, ancak tam tersi olamaz. Bu iyi bir argüman olabilir. Ayrıca kapsüllemeyi dil özelliğinden çok bir kural olarak görüyorum (genellikle yansıma yoluyla kapsüllemeyi kırabilirsiniz). Polimorfizm ile ilgili olarak - elde ettiğiniz tek şey yöntem argümanlarını kontrol ederken bazı basit "if" koşulları yazmak zorunda değildir (ve derleme sırasında hedef yöntem çözülürse biraz hız). Burada gerçek bir JavaScript dezavantajı yoktur.
Pavel Horal

Prototipler harika, IMO. Haskell gibi işlevsel bir dil yaratmayı düşünüyorum ... ama soyutlamalar yaratmak yerine her şeyi prototiplere dayandıracağım. Toplamı genelleştirmek ve "katlamak" için faktöriyel yerine, toplam fonksiyonunun prototipini ve ürün yapmak için + işaretini * ve 0 yerine 1 ile değiştirmelisiniz. Ben "Monads" vaat / geri aramalar yerine "o zaman" yerine "o zaman" eş anlamlı olan flatMap prototip olarak açıklayacağım. Prototiplerin işlevsel programlamayı kitlelere getirmeye yardımcı olabileceğini düşünüyorum.
aoeu256

11

İki yöntem arasında gerçekten fazla bir şey yok. Anlaşılması gereken temel fikir, JavaScript motoruna okunacak bir nesnenin özelliği verildiğinde, önce örneği ve bu özellik eksikse prototip zincirini kontrol etmesidir. Prototippal ve klasik arasındaki farkı gösteren bir örnek:

prototypal

var single = { status: "Single" },
    princeWilliam = Object.create(single),
    cliffRichard = Object.create(single);

console.log(Object.keys(princeWilliam).length); // 0
console.log(Object.keys(cliffRichard).length); // 0

// Marriage event occurs
princeWilliam.status = "Married";

console.log(Object.keys(princeWilliam).length); // 1 (New instance property)
console.log(Object.keys(cliffRichard).length); // 0 (Still refers to prototype)

Örnek yöntemleriyle klasik (Her örnek kendi özelliğini depoladığı için verimsiz)

function Single() {
    this.status = "Single";
}

var princeWilliam = new Single(),
    cliffRichard = new Single();

console.log(Object.keys(princeWilliam).length); // 1
console.log(Object.keys(cliffRichard).length); // 1

Verimli klasik

function Single() {
}

Single.prototype.status = "Single";

var princeWilliam = new Single(),
    cliffRichard = new Single();

princeWilliam.status = "Married";

console.log(Object.keys(princeWilliam).length); // 1
console.log(Object.keys(cliffRichard).length); // 0
console.log(cliffRichard.status); // "Single"

Gördüğünüz gibi, klasik tarzda beyan edilen “sınıflar” prototipini değiştirmek mümkün olduğundan, prototip mirasını kullanmanın gerçekten bir yararı yoktur. Klasik yöntemin bir alt kümesidir.


2
Bu konuyla ilgili diğer yanıtlara ve kaynaklara bakıldığında, cevabınız şu şekilde görünüyor: "Prototipal kalıtım, klasik kalıtımın görünmesine izin vermek için JavaScript'e eklenen sözdizimsel şekerin bir alt kümesidir". OP, JavaScript'teki örnekleme tekniklerini karşılaştırmak yerine, JS'deki prototipal kalıtımın diğer dillerde klasik kalıtımdan yararlarını soruyor gibi görünüyor.
Fader Darkly

2

Web Geliştirme: Prototippal Kalıtım ve Klasik Kalıtım

http://chamnapchhorn.blogspot.com/2009/05/prototypal-inheritance-vs-classical.html

Klasik Vs prototip kalıtım - Yığın Taşması

Klasik Vs prototip kalıtım


20
Ben başka bir SO bağlantısı sürece, bağlantı (kendim yapmak için kullanılan bir şey) yapıştırma yerine bağlantıların içeriğini özetlemek daha iyi olduğunu düşünüyorum. Bunun nedeni, bağlantıların / sitelerin azalması ve soruya verilen yanıtı kaybetmenizdir ve potansiyel olarak arama sonuçlarını etkiler.
James Westgate

İlk bağlantı neden prototip palet mirasına cevap vermiyor ? Basitçe açıklar.
viebel
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.