Herança de prototipagem

Como outros tipos de dados, uma herda propriedades e métodos de um protótipo Object integrado. o que significa que o objeto resultante contém as propriedades definidas e uma prototipagem com os métodos herdados do protótipo:

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

As propriedades do protótipo não são acessadas diretamente pela chave de propriedade. Conforme como você pode notar no exemplo anterior, isso está implícito no [[prototype]] ou <prototype> usada nos navegadores consoles para desenvolvedores e fontes documentação da chave de propriedade do protótipo:

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

Embora todos os navegadores mais comuns usem __proto__ como o padrão real, isso não é formalmente padronizadas e deve ser evitado no código de produção.

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

Em vez disso, é possível acessar e modificar diretamente o [[Prototype]] de um objeto usando o Object.getPrototypeOf() e o Object.setPrototypeOf() integrados métodos:

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 } 

Para diferenciar propriedades herdadas de propriedades definidas pelo autor, o última é normalmente chamada de "propriedades próprias" do objeto.

O método Object.hasOwn() integrado vai retornar true se a propriedade especificada é uma propriedade direta do objeto e false se a propriedade é herdada ou não existe. Sempre que possível, use Object.hasOwn() em vez do método hasOwnProperty() herdado, que não é compatível com 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 

Teste seu conhecimento

Por que evitar o uso de __proto__?

Ele não é padronizado.
Ela não é compatível com muitos navegadores.
Isso vai confundir os futuros mantenedores do código.