Pewarisan prototipe

Seperti jenis data lainnya, objek mewarisi properti dan metode dari prototipe Object bawaan, artinya objek yang dihasilkan berisi properti yang telah Anda tentukan dan properti prototipe yang berisi metode yang diwarisi dari prototipe:

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__()

Properti prototipe tidak dimaksudkan untuk diakses langsung oleh kunci properti. Sebagai yang mungkin Anda perhatikan dalam contoh sebelumnya, hal ini tersirat oleh [[prototype]] atau notasi <prototype> yang digunakan di browser konsol developer dan sumber dokumentasi untuk kunci properti prototipe:

// Chrome:
let emptyObject = {};

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

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

Meskipun semua browser umum menggunakan __proto__ sebagai standar de facto, ini bukanlah distandarisasi secara formal dan harus dihindari dalam kode produksi.

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__()

Sebagai gantinya, Anda dapat langsung mengakses dan mengubah [[Prototype]] objek menggunakan Object.getPrototypeOf() dan Object.setPrototypeOf() bawaan metode:

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 }

Untuk membedakan antara properti yang diwariskan dan properti yang ditentukan penulis, biasanya disebut "properti memiliki" objek.

Metode Object.hasOwn() bawaan akan menampilkan true jika properti yang ditentukan adalah properti langsung objek, dan false jika properti diwariskan atau tidak ada. Jika memungkinkan, gunakan Object.hasOwn() bukan metode hasOwnProperty() yang diwarisi, yang tidak mendukung 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

Menguji pemahaman Anda

Mengapa Anda harus menghindari penggunaan __proto__?

Tidak terstandardisasi.
Tidak didukung oleh banyak browser.
Hal ini akan membingungkan pengelola kode Anda di masa mendatang.