Klass Obyektni kengaytiradimi?
Ma’lumki, barcha obyektlar odatda Object.prototype
dan meros bo’lib, hasOwnProperty
va boshqalar kabi “umumiy” obyekt usullariga kirish huquqiga ega.
Masalan:
class Rabbit {
constructor(name) {
this.name = name;
}
}
let rabbit = new Rabbit("Rab");
// hasOwnProperty method is from Object.prototype
alert( rabbit.hasOwnProperty('name') ); // true
Agar biz uni "class Rabbit extends Object"
kabi aniq yozsak, natija oddiy "class Rabbit"
dan farq qiladimi?
Farqi nima?
Mana bunday kodning misoli (u ishlamaydi – nima uchun? uni tuzating):
class Rabbit extends Object {
constructor(name) {
this.name = name;
}
}
let rabbit = new Rabbit("Rab");
alert(rabbit.hasOwnProperty("name")); // Error
Birinchidan, nima uchun oxirgi kod ishlamasligini ko’rib chiqamiz.
Agar biz uni ishlatishga harakat qilsak, sabab aniq bo’ladi. Meros klass konstruktori super()
ni chaqirishi kerak. Aks holda "this"
“aniqlanmaydi”.
Shunday qilib, tuzatish:
class Rabbit extends Object {
constructor(name) {
super(); // meros olishda ota konstruktorni chaqirish kerak
this.name = name;
}
}
let rabbit = new Rabbit("Rab");
alert( rabbit.hasOwnProperty('name') ); // true
Ammo bu hali hammasi emas.
Tuzatishdan keyin ham, "class Rabbit extends Object"
va class Rabbit
o’rtasida hali ham muhim farq bor.
Ma’lumki, “kengaytirish” sintaksisida ikkita prototip mavjud:
- Konstruktor funktsiyalarining
"prototype"
o’rtasida (usullar uchun). - Konstruktor funktsiyalari orasida (statik usullar uchun).
Bizning holatimizda, class Rabbit extends Object
uchun bu quyidagilarni anglatadi:
class Rabbit extends Object {}
alert(Rabbit.prototype.__proto__ === Object.prototype); // (1) true
alert(Rabbit.__proto__ === Object); // (2) true
Shunday qilib, Rabbit
endi Rabbit
orqali Object
ning statik usullariga kirishni ta’minlaydi:
class Rabbit extends Object {}
// odatda bizchaqiramiz Object.getOwnPropertyNames
alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // a,b
Agar bizda extends Object
bo’lmasa, Rabbit.__ proto__
Object
ga o’rnatilmagan.
Mana demo:
class Rabbit {}
alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true
alert( Rabbit.__proto__ === Object ); // (2) false (!)
alert( Rabbit.__proto__ === Function.prototype ); // sukut bo'yicha har qanday funktsiya sifatida
// xato, Rabbit-da bunday funktsiya yo'q
alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // Error
Shunday qilib, Rabbit
bu holda Object
ning statik usullariga kirishni ta’minlamaydi.
Aytgancha, Function.prototype
“umumiy” funktsiya usullariga ega, masalan call
, bind
va boshqalar. Ikkala holatda ham ular mavjud, chunki Object
konstruktori Object.__ proto__ = == Funktsiya.prototype
.
Here’s the picture:
Shunday qilib, qisqacha aytganda, ikkita farq bor:
class Rabbit | class Rabbit extends Object |
---|---|
– | konstruktorda super() ni chaqirish kerak |
Rabbit.__proto__ === Function.prototype |
Rabbit.__proto__ === Object |