Pewarisan prototipe

Seperti jenis data lainnya, objek mewarisi properti dan metode dari prototipe Object bawaan, yang berarti 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. Seperti yang mungkin Anda lihat dalam contoh sebelumnya, hal ini ditunjukkan oleh notasi [[prototype]] atau <prototype> yang digunakan di konsol developer browser 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, hal ini tidak distandardisasi 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 metode Object.getPrototypeOf() dan Object.setPrototypeOf() bawaan:

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, properti yang terakhir biasanya disebut "properti sendiri" objek.

Metode Object.hasOwn() bawaan menampilkan true jika properti yang ditentukan adalah properti langsung dari objek, dan false jika properti diwarisi 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 sebaiknya tidak menggunakan __proto__?

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