Come altri tipi di dati, una eredita proprietà e metodi da un prototipo Object integrato, nel senso che l'oggetto risultante contiene sia le proprietà definite che proprietà prototype contenente i metodi ereditati dal prototipo:
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__() Non è possibile accedere direttamente alle proprietà prototipazione tramite la chiave della proprietà. Come come puoi notare nell'esempio precedente, ciò è implicito nell'[[prototype]] o la notazione <prototype> utilizzata nei browser per gli sviluppatori e le loro origini documentazione per la chiave di proprietà del prototipo:
// Chrome: let emptyObject = {}; emptyObject; > {} [[prototype]]: Object // Firefox: let emptyObject = {}; emptyObject; > Object { } <prototype>: Object { … } Sebbene tutti i browser comuni utilizzino __proto__ come standard di fatto, non si tratta formalmente standardizzata e da evitare nel codice di produzione.
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__() Puoi invece accedere direttamente all'elemento [[Prototype]] di un oggetto e modificarlo usando le funzionalità integrate Object.getPrototypeOf() e Object.setPrototypeOf() metodo:
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 } Per distinguere tra proprietà ereditate e proprietà definite dall'autore, la seconda è generalmente chiamata "proprietà dell'oggetto".
Il metodo Object.hasOwn() integrato restituisce true se la proprietà specificata è una proprietà diretta dell'oggetto e false se la proprietà viene ereditata o non esiste. Se possibile, utilizza Object.hasOwn() anziché il metodo hasOwnProperty()ereditato, che non supporta 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 Verifica le tue conoscenze
Perché dovresti evitare di usare __proto__?