توريث النموذج الأولي

مثل أنواع البيانات الأخرى، يرث الكائن الخصائص والطرق من نموذج Object المدمج، مما يعني أن الكائن الناتج يحتوي على الخصائص التي حددتها خاصية النموذج الأوّلي التي تحتوي على الطرق الموروثة من النموذج الأوّلي:

let myObject = {
    'booleanValue' : true
};

myObject;
> Object { booleanValue: true }
    booleanValue: true
    [[prototype]]: Object { … }
            __defineGetter__: function __defineGetter__()
            __defineSetter__: function __defineSetter__()
            __lookupGetter__: function __lookupGetter__()
            __lookupSetter__: function __lookupSetter__()
            __proto__: …
                constructor: function Object()
                hasOwnProperty: function hasOwnProperty()
                isPrototypeOf: function isPrototypeOf()
                propertyIsEnumerable: function propertyIsEnumerable()
                toLocaleString: function toLocaleString()
                toString: function toString()
                valueOf: function valueOf()
                <get __proto__()>: function __proto__()
                <set __proto__()>: function __proto__()

لا يُقصد من خصائص النموذج الأوّلي الوصول إليها مباشرةً عن طريق مفتاح الملكية. بالنسبة قد تلاحظ في المثال السابق، هذا متضمن في [[prototype]] أو علامة <prototype> المستخدمة في المتصفّحات وحدات تحكّم المطوّرين ومصادر وثائق لمفتاح خاصية النموذج الأولي:

// Chrome:
let emptyObject = {};

emptyObject;
> {}
  [[prototype]]: Object
// Firefox:
let emptyObject = {};

emptyObject;
> Object {  }
  <prototype>: Object { … }

على الرغم من أنّ جميع المتصفحات الشائعة تستخدم __proto__ كمعيار فعلي، إلا أنّ ذلك ليس موحّدة رسميًا ويجب تجنبها في رمز الإنتاج.

let emptyObject = {};

emptyObject.__proto__;
> Object { … }
    __defineGetter__: function __defineGetter__()
    __defineSetter__: function __defineSetter__()
    __lookupGetter__: function __lookupGetter__()
    __lookupSetter__: function __lookupSetter__()
    __proto__:
        constructor: function Object()
        hasOwnProperty: function hasOwnProperty()
        isPrototypeOf: function isPrototypeOf()
        propertyIsEnumerable: function propertyIsEnumerable()
        toLocaleString: function toLocaleString()
        toString: function toString()
        valueOf: function valueOf()
        <get __proto__()>: function __proto__()
        <set __proto__()>: function __proto__()

بدلاً من ذلك، يمكنك الوصول مباشرةً إلى [[Prototype]] لعنصر وتعديلها. باستخدام Object.getPrototypeOf() وObject.setPrototypeOf() المدمَجَين الطرق:

let myObj = { "value" : 5 };
let protoParent = { "protoValue" : true };

myObj;
Object { value: 5 }
    value: 5
    <prototype>: Object { … }

Object.getPrototypeOf( myObj );
> Object { … }
    __defineGetter__: function __defineGetter__()
    __defineSetter__: function __defineSetter__()
    __lookupGetter__: function __lookupGetter__()
    __lookupSetter__: function __lookupSetter__()
    __proto__:
    constructor: function Object()
    hasOwnProperty: function hasOwnProperty()
    isPrototypeOf: function isPrototypeOf()
    propertyIsEnumerable: function propertyIsEnumerable()
    toLocaleString: function toLocaleString()
    toString: function toString()
    valueOf: function valueOf()
    <get __proto__()>: function __proto__()
    <set __proto__()>: function __proto__()

Object.setPrototypeOf( myObj, protoParent );
> Object { value: 5 }
    value: 5
    <prototype>: Object { protoValue: true }

للتمييز بين الخصائص الموروثة والخصائص التي يحددها المؤلف، ويُطلق على الأخير عادةً "الخصائص الخاصة" للكائن.

تعرض طريقة Object.hasOwn() المضمنة القيمة true إذا كانت السمة المحددة هي خاصية مباشرة للكائن، وfalse إذا كانت الخاصية موروثة أو غير موجود. استخدِم Object.hasOwn() كلما أمكن ذلك. بدلاً من الطريقة hasOwnProperty() الموروثة التي لا تتوافق Object.create()

let myObject = {
    'myValue' : 100
};

Object.hasOwn( myObject, 'myValue' );
> true

myObject.__proto__; // The Object prototype inherited by `myObject` is present:
> Object { … }

Object.hasOwn( myObject, '__proto__' ); // The Object prototype inherited by `myObject` is not an "own property:"
> false

التحقق من فهمك

لماذا عليك تجنُّب استخدام __proto__؟

وهي غير موحدة.
ولا يمكن استخدام هذه العلامة في العديد من المتصفّحات.
سيؤدي ذلك إلى إرباك المستخدمين المستقبليين برموزك البرمجية.