ירושה של אב טיפוס

כמו סוגי נתונים אחרים, אובייקט יורש מאפיינים ושיטות מאב טיפוס מובנה של 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> שבשימוש בדפדפנים Developer Console והמקורות תיעוד למפתח המאפיין של אב הטיפוס:

// 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 }

כדי להבחין בין נכסים שעברו בירושה לנכסים שהוגדרו על ידי המחבר, הפרמטר האחרון נקרא בדרך כלל 'נכסים דיגיטליים' של האובייקט.

ה-method המובנה Object.hasOwn() מחזירה true אם המאפיין שצוין הוא מאפיין ישיר של האובייקט, ו-false אם הנכס עובר בירושה או לא קיים. כשאפשר, מומלץ להשתמש ב-Object.hasOwn() במקום להשתמש ב-method 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__?

אין תקן.
דפדפנים רבים לא תומכים בו.
הפעולה הזאת תגרום לבלבול אצל מנהלים עתידיים של הקוד.