Sınıf Object'i genişletir mi?
Bildiğiniz gibi objeler Object.prototype’tan kalıtım alır ve “generic” obje metodlarına bu şekilde erişir.
Aşağıda gösterildiği gibi:
class Rabbit {
constructor(name) {
this.name = name;
}
}
let rabbit = new Rabbit("Rab");
// hasOwnProperty method is from Object.prototype
// rabbit.__proto__ === Object.prototype
alert( rabbit.hasOwnProperty('name') ); // true
Pek, "class Rabbit extends Object" ile "class Rabbit" aynımıdır, öyleyse neden?
Aşağıdaki kod çalışır mı?
class Rabbit extends Object {
constructor(name) {
this.name = name;
}
}
let rabbit = new Rabbit("Rab");
alert( rabbit.hasOwnProperty('name') ); // true
Eğer çalışmaz ise çalışır hale getiriniz.
Cevap iki parçadan oluşmaktadır
Birinci bölüm, kolay olan kalıtım yapan sınıf yapıcı metodda super()'i çağırmalıdır. Diğer türlü "this" “tanımsız” olacaktır.
Çözümü şu şekildedir:
class Rabbit extends Object {
constructor(name) {
super(); // kalıtım yapıldığında üst sınıf çağırılmalıdır.
this.name = name;
}
}
let rabbit = new Rabbit("Rab");
alert( rabbit.hasOwnProperty('name') ); // true
Fakat henüz bitmedi.
Bu problem düzeltildikten sonra bile, "class Rabbit extends Object" ile class Rabbit arasında önemli bir fark vardır.
Bildiğiniz gibi “extends” yazımı iki prototip kurar:
- Yapıcı fonksiyonların
"prototype"ları arasında ( metodlar için ) - Yapıcı fonksiyonların kendileri arasında ( statik metodlar için )
Bizim durumumuzda class Rabbit extends Object:
class Rabbit extends Object {}
alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true
alert( Rabbit.__proto__ === Object ); // (2) true
anlamına gelir.
Object’in statik metodlarına Rabbit ile şu şekilde erişebiliriz:
class Rabbit extends Object {}
// normlade Object.getOwnPropertyNames'i çağırırız.
alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // a,b
Eğer extends kullanılmaz ise class Rabbit ikinci referansı alamaz.
Aşağıdaki ile karşılaştırabilirsiniz:
class Rabbit {}
alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true
alert( Rabbit.__proto__ === Object ); // (2) false (!)
// hata, Rabbit diye bir fonksiyon bulunmamaktadır.
alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // Hata
Basit class Rabbit için Rabbit fonksiyonu aynı prototipe sahiptir.
class Rabbit {}
// (2) yerine kullanılır. Rabbit için doğrudur. (diğer fonksiyonlar için de)
alert( Rabbit.__proto__ === Function.prototype );
Bu arada Function.prototype’ın “generic” fonksiyonları bulunmaktadır. Bunlar, call, bind vs gibi metodlardır. Her iki durumda da bunlar mevcuttur çünkü Object yapısında varsayılan olarak bulunmaktadır. Object.__proto__ === Function.prototype
Son tahlilde görüntü şu şekildedir:
Özetlersek:
| class Rabbit | class Rabbit extends Object |
|---|---|
| – | yapıcı metodda super() çağırılmalıdır. |
Rabbit.__proto__ === Function.prototype |
Rabbit.__proto__ === Object |