การสืบทอดต้นแบบ

เช่นเดียวกับข้อมูลประเภทอื่นๆ ได้รับคุณสมบัติและเมธอดมาจากต้นแบบ 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__

ซึ่งจะทำให้ผู้ดูแลโค้ดของคุณในอนาคตสับสน
เบราว์เซอร์จำนวนมากไม่รองรับฟีเจอร์นี้
โดยไม่ได้เป็นมาตรฐาน