2011-07-05 14 views
5

JS'de "alma" kalıtımını denemeye çalışıyorum. Sadece temelde başka bir bir nesneden tüm özelliklerini kopyalamak için düzgün bir yol keşfetti:Kalıtım: this.base = Class(); this.base() veya ...?

function Person(name){ 
    this.name="Mr or Miss: "+name; 

    this.introduce = function(){ 
    console.log("Hi, I am "+this.name); 
    } 
} 

function Employee(name,title){ 
    this.title=title; 

    this.base=Person; 
    this.base(name); 

} 

e = new Employee('tony', 'manager') 
e.introduce(); 

Not Bir kurucu ile Kişi() sınıf var ve bunun niteliği "ad" yapıcı tarafından oluşturulur. Bununla ilgili en önemli şey, aynı zamanda çalışanın ALSO adını yapıcıya (ve voila'ya) sahip olmasıdır, aynı parametreyi kullanarak Kişi nesnesini oluşturur. şimdi ne ....

function Person(name){ 

    this.introduce = function(){ 
    console.log("Hi, I am "+this.name); 
    } 
} 

function Employee(name, title){ 
    this.name = name; /* ?!?!?!?!? I can't call the proper constructor here */ 
    this.title = title; 
} 
Employee.prototype= new Person(); /* ?!?!? NO NAME HERE..>? */ 
Employee.prototype.constructor = Employee; 


e = new Employee('tony', 'manager') 
e.introduce(); 

Err:

ben "Prototip" yolu ile bu yapmış olsaydı? Bunu bile tamamlayamıyorum: Çalışandaki this.name, uygun Kişi yapıcısı kullanılarak ayarlanamaz; Bir Şahıs nesnesinin yaratılması mirasta sadece bir kez olur.

Öyleyse neyi özlüyorum? İlk örneğim davamda gitme yolunu mu? İkinci örnekle aynı sonucu elde etmenin bir yolu var mı?

Yardım!

function Parent() {} 

function Child() { 
    Parent.call(this); // call the constructor of the parent 
} 

var Constr = function() {}; 
Constr.prototype = Parent.prototype; 

Child.prototype = new Constr(); 
Child.prototype.constructor = Child; 

Yani "hile" boş işleve prototip olarak Parent.prototype atamak ve Child prototipi olarak bu işlevin yeni bir örneğini oluşturmaktır:

cevap

9

prototip miras Bu tür genellikle bu şekilde yapılır .

Bu, Child.prototype'un uzatılması Parent.prototype'u uzatmayacak şekilde yapılır.

Ayrıca, üst kurucunun alt öğesinin yapıcısını da çağırmalısınız. Sanırım bu, uğraştığın kısım. Her fonksiyonun call[docs] ve apply[docs] yöntemine sahip olması, this öğesinin açık bir şekilde ayarlamanıza izin verir. Örneğin bir özelliğine yapıcı atamadan

function Employee(name,title){ 
    this.title=title; 

    Person.call(this, name); 
} 

: En örnekte

, bu gibi görünecektir.

Örneğinizde, this.base(name), yapının örneğin bir özelliğine atanmasıyla (ve bu şekilde çağırılarak) çalıştığı için, işlevin içindeki this, bu örneğe başvurur. Bu modeli uygulayan çeşitli kütüphaneler vardır, örn. Google Closure library: Ama:

goog.inherits = function(childCtor, parentCtor) { 
    /** @constructor */ 
    function tempCtor() {}; 
    tempCtor.prototype = parentCtor.prototype; 
    childCtor.superClass_ = parentCtor.prototype; 
    childCtor.prototype = new tempCtor(); 
    childCtor.prototype.constructor = childCtor; 
}; 
+0

Ben bu yanıt için ne kadar minnettar ifade edemez ... – Merc

+0

Tamamen (D vay, yere almak gerekir) Google Kapatma kitaplığında fonksiyonlarını anlamak! Anladığım kadarıyla, türetilmiş bir sınıf oluşturduğumda, iç öznitelikleri mi yoksa Parent.call (this) yazarak yazmak istemiyorum; veya Parent.call (bu, isim) - bu doğru mu? Bunu yapmak istiyorsan, her zaman yapmak istemez miydin? – Merc

+0

@Tony: Bence yaparsın. Ama eğer klasik kalıtım göz önüne alındığında (Java gibi), eğer bunun üzerine yazarsanız ebeveynin yapıcısını da çağırmalısınız.Tek fark şudur: JavaScript'te temelde * her zaman * kurucunun üzerine yazmalısınız çünkü sınıfları nasıl simüle ediyoruz. Yani aslında o kadar farklı değil ve belki de neler olduğunu anlamak daha da kolay. –