نريد أن نتيح هذا المشروع المفتوح المصدر إلى كل الناس حول العالم. من فضلك ساعدنا على ترجمة محتوى هذه السلسله للغة التى تعرفها.
الرجوع الي الدرس

فئة تمدد الكائن؟

كما نعلم ، عادة ما ترث جميع الكائنات من Object.prototype وتحصل على طرق للكائنات" العامة "مثلhasOwnProperty وما إلى ذلك.

على سبيل المثال:

class Rabbit {
  constructor(name) {
    this.name = name;
  }
}

let rabbit = new Rabbit("Rab");

// hasOwnProperty method is from Object.prototype
alert( rabbit.hasOwnProperty('name') ); // true

ولكن إذا وضحناها صراحة مثل “class class rabbit Extended Object” ، فستكون النتيجة مختلفة عن “class rabbit” بسيطة؟

ماهو الفرق؟

فيما يلي مثال لمثل هذا الرمز (لا يعمل – لماذا؟ إصلاحه؟):

class Rabbit extends Object {
  constructor(name) {
    this.name = name;
  }
}

let rabbit = new Rabbit("Rab");

alert( rabbit.hasOwnProperty('name') ); // Error

أولاً ، دعنا نرى لماذا لا يعمل الكود الأخير.

يصبح السبب واضحًا إذا حاولنا تشغيله. يجب على مُنشئ الفصل الموروث استدعاء `` super () `. وإلا فلن يتم تحديد “هذا” ".

إذن هذا هو الإصلاح:

class Rabbit extends Object {
  constructor(name) {
    super(); // need to call the parent constructor when inheriting
    this.name = name;
  }
}

let rabbit = new Rabbit("Rab");

alert( rabbit.hasOwnProperty('name') ); // true

لكن هذا ليس كل شيء بعد.

حتى بعد الإصلاح ، لا يزال هناك اختلاف مهم في “class rabbit يوسع الكائن” “مقابل” class Rabbit ".

كما نعلم ، فإن الصيغة “الممتدة” تضع نموذجين أوليين:

  1. بين “النموذج” لوظائف المنشئ (للطرق).
  2. بين وظائف المنشئ أنفسهم (للأساليب الثابتة).

في حالتنا ، تعني كلمة “أرنب يمتد الكائن” ما يلي:

class Rabbit extends Object {}

alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true
alert( Rabbit.__proto__ === Object ); // (2) true

إذن يوفر “الأرنب” الآن إمكانية الوصول إلى الأساليب الثابتة لـ “الكائن” عبر “الأرنب” ، على النحو التالي:

class Rabbit extends Object {}

// normally we call Object.getOwnPropertyNames
alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // a,b

ولكن إذا لم يكن لدينا Extended Object ، فلن يتم تعيينRabbit .__ proto__ على Object.

هنا هو العرض التوضيحي:

class Rabbit {}

alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true
alert( Rabbit.__proto__ === Object ); // (2) false (!)
alert( Rabbit.__proto__ === Function.prototype ); // as any function by default

// error, no such function in Rabbit
alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // Error

لذا Rabbit لا يوفر الوصول إلى الأساليب الثابتة لـ “الكائن” في هذه الحالة.

بالمناسبة ، يحتوي Function.prototype على طرق وظيفية" عامة "، مثلcall وbind وما إلى ذلك. وهي متاحة في النهاية في كلتا الحالتين ، لأن مُنشئ Object المدمج ،Object .__ proto__ = == Function.prototype.

ها هي الصورة:

لذلك ، باختصار ، هناك اختلافان:

class Rabbit class Rabbit extends Object
needs to call super() in constructor
Rabbit.__proto__ === Function.prototype Rabbit.__proto__ === Object