Like other data types, an
object inherits properties and methods from a built-in Object prototype,
meaning the resulting object contains both the properties you've defined and a
prototype property containing the methods inherited from the prototype:
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 properties aren't intended to be accessed directly by property key. As
you might notice in the previous example, this is implied by the [[prototype]]
or <prototype> notation used in browsers' developer consoles and sources of
documentation for the prototype's property key:
// Chrome:
let emptyObject = {};
emptyObject;
> {}
  [[prototype]]: Object
// Firefox:
let emptyObject = {};
emptyObject;
> Object {  }
  <prototype>: Object { … }
Though all common browsers use __proto__ as a de facto standard, this isn't
formally standardized and should be avoided in production code.
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__()
Instead, you can directly access and modify the [[Prototype]] of an object
using the built-in Object.getPrototypeOf() and Object.setPrototypeOf()
methods:
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 }
To differentiate between inherited properties and author-defined properties, the latter is typically called the object's "own properties."
The built-in Object.hasOwn() method returns true if the specified property
is a direct property of the object, and false if the property is inherited or
doesn't exist. Whenever possible, use Object.hasOwn()
instead of the inherited hasOwnProperty()method, which doesn't support
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
Check your understanding
Why should you avoid using __proto__?