TLDR; Süper gerekli değildir, ancak muhtemelen uzun vadede yardımcı olacaktır ve bunu yapmak daha doğrudur.
NOT: Önceki cevabım kafa karıştırıcı bir şekilde yazılmış ve cevaplamak için acele ettiğim bazı hatalar olduğu için çok fazla düzenlenmişti. Bazı korkunç hatalara dikkat çekenlere teşekkürler.
Temel olarak, Javascript alt sınıflandırma doğru tel bağlamaktır. Alt sınıfa girdiğimizde, prototip delegasyonunun bir prototypenesnenin üzerine yazılması da dahil olmak üzere düzgün çalıştığından emin olmak için bazı korkak şeyler yapmalıyız . Bir prototypenesnenin üzerine yazmak constructor, bu nedenle referansı düzeltmemiz gerekir.
ES5'teki 'sınıfların' nasıl çalıştığını hızlıca inceleyelim.
Diyelim ki bir yapıcı işleviniz ve onun prototipi var:
//Constructor Function
var Person = function(name, age) {
this.name = name;
this.age = age;
}
//Prototype Object - shared between all instances of Person
Person.prototype = {
species: 'human',
}
Kurucuyu somutlaştırmak için çağırdığınızda şunları söyleyin Adam:
// instantiate using the 'new' keyword
var adam = new Person('Adam', 19);
new'Kişi' ile çağrılan anahtar kelime temelde kod birkaç ek çizgilerle Kişi yapıcısı çalışacaktır:
function Person (name, age) {
// This additional line is automatically added by the keyword 'new'
// it sets up the relationship between the instance and the prototype object
// So that the instance will delegate to the Prototype object
this = Object.create(Person.prototype);
this.name = name;
this.age = age;
return this;
}
/* So 'adam' will be an object that looks like this:
* {
* name: 'Adam',
* age: 19
* }
*/
Biz ise console.log(adam.species), arama başarısız olur adammesela ve onun için prototypal zincirini bakmak .prototypeolduğunu Person.prototype- ve Person.prototype sahip bir .speciesarama başarılı olur, böylece özelliği Person.prototype. Daha sonra günlüğe kaydedilir 'human'.
Burada, Person.prototype.constructordoğru bir şekilde işaret edecektir Person.
Şimdi ilginç kısım, sözde 'alt sınıflama'. Bir Studentsınıf oluşturmak istiyorsak , bu Personbazı ek değişikliklerle sınıfın bir alt sınıfıdır, Student.prototype.constructordoğruluk için Öğrenci'ye işaret ettiğinden emin olmamız gerekir .
Bunu tek başına yapmaz. Alt sınıf oluşturduğunuzda, kod şöyle görünür:
var Student = function(name, age, school) {
// Calls the 'super' class, as every student is an instance of a Person
Person.call(this, name, age);
// This is what makes the Student instances different
this.school = school
}
var eve = new Student('Eve', 20, 'UCSF');
console.log(Student.prototype); // this will be an empty object: {}
new Student()Burada çağrı yapmak istediğimiz tüm özelliklere sahip bir nesne döndürür. Burada, kontrol edersek eve instanceof Person, dönecekti false. Eğer erişmeye çalışırsak eve.species, geri dönecekti undefined.
Başka bir deyişle, delege doğru şekilde eve instanceof Persondönecek ve Studentdelege örnekleri doğru bir şekilde Student.prototypeve sonra olacak şekilde kablolamalıyız Person.prototype.
AMA newanahtar kelimeyle çağırdığımızdan , bu çağrının ne eklediğini hatırlıyor musunuz? Buna Object.create(Student.prototype), Studentve arasındaki delegasyonel ilişkiyi böyle kurduk Student.prototype. Şu anda Student.prototypeboş olduğunu unutmayın . Bu nedenle, .speciesbir örneğini aramak yalnızcaStudent temsilci seçerken başarısız olur ve mülk üzerinde mevcut değildir . Student.prototype.speciesStudent.prototype
Biz atama yaptığımızda Student.prototypeiçin Object.create(Person.prototype), Student.prototypeiçin kendisi daha sonra delegelere Person.prototypeve yukarı seyir eve.speciesdönecektir humanbeklediğimiz gibi. Muhtemelen Student.prototype AND Person.prototype'den miras almasını isteriz. Yani hepsini düzeltmemiz gerekiyor.
/* This sets up the prototypal delegation correctly
*so that if a lookup fails on Student.prototype, it would delegate to Person's .prototype
*This also allows us to add more things to Student.prototype
*that Person.prototype may not have
*So now a failed lookup on an instance of Student
*will first look at Student.prototype,
*and failing that, go to Person.prototype (and failing /that/, where do we think it'll go?)
*/
Student.prototype = Object.create(Person.prototype);
Şimdi delegasyon çalışıyor, ancak Student.prototypebir ile yazıyoruz Person.prototype. Eğer ararsak Student.prototype.constructor, bunun Personyerine işaret eder Student. Bu yüzden düzeltmemiz gerekiyor.
// Now we fix what the .constructor property is pointing to
Student.prototype.constructor = Student
// If we check instanceof here
console.log(eve instanceof Person) // true
ES5'te, mülkümüz constructor'yapıcı' olma niyetiyle yazdığımız bir işleve gönderme yapan bir referanstır. newAnahtar kelimenin bize verdiklerinin yanı sıra , yapıcı aksi takdirde 'düz' bir işlevdir.
ES6'da, constructorşimdi sınıf yazma şeklimizde yerleşiktir - olduğu gibi, bir sınıf ilan ettiğimizde bir yöntem olarak sağlanır. Bu sadece sözdizimsel şekerdir, ancak var superolan bir sınıfı genişletirken bir zamana erişim gibi bazı kolaylıklar sağlıyor . Yani yukarıdaki kodu şöyle yazardık:
class Person {
// constructor function here
constructor(name, age) {
this.name = name;
this.age = age;
}
// static getter instead of a static property
static get species() {
return 'human';
}
}
class Student extends Person {
constructor(name, age, school) {
// calling the superclass constructor
super(name, age);
this.school = school;
}
}