Like other data types, an object inherits properties and methods from a built-in Object
, meaning the resulting object contains both the properties you've defined and a property containing the methods inherited from the :
let myObject = {
'booleanValue' : true
};
myObject;
> Object { booleanValue: true }
booleanValue: true
[[]]: Object { … }
__defineGetter__: function __defineGetter__()
__defineSetter__: function __defineSetter__()
__lookupGetter__: function __lookupGetter__()
__lookupSetter__: function __lookupSetter__()
__proto__: …
constructor: function Object()
hasOwnProperty: function hasOwnProperty()
isOf: function isOf()
propertyIsEnumerable: function propertyIsEnumerable()
toLocaleString: function toLocaleString()
toString: function toString()
valueOf: function valueOf()
<get __proto__()>: function __proto__()
<set __proto__()>: function __proto__()
properties aren't intended to be accessed directly by property key. As you might notice in the previous example, this is implied by the [[]]
or <>
notation used in browsers' developer consoles and sources of documentation for the 's property key:
// Chrome:
let emptyObject = {};
emptyObject;
> {}
[[]]: Object
// Firefox:
let emptyObject = {};
emptyObject;
> Object { }
<>: 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()
isOf: function isOf()
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 [[]]
of an object using the built-in Object.getOf()
and Object.setOf()
methods:
let myObj = { "value" : 5 };
let protoParent = { "protoValue" : true };
myObj;
Object { value: 5 }
value: 5
<>: Object { … }
Object.getOf( myObj );
> Object { … }
__defineGetter__: function __defineGetter__()
__defineSetter__: function __defineSetter__()
__lookupGetter__: function __lookupGetter__()
__lookupSetter__: function __lookupSetter__()
__proto__:
constructor: function Object()
hasOwnProperty: function hasOwnProperty()
isOf: function isOf()
propertyIsEnumerable: function propertyIsEnumerable()
toLocaleString: function toLocaleString()
toString: function toString()
valueOf: function valueOf()
<get __proto__()>: function __proto__()
<set __proto__()>: function __proto__()
Object.setOf( myObj, protoParent );
> Object { value: 5 }
value: 5
<>: 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 inherited by `myObject` is present:
> Object { … }
Object.hasOwn( myObject, '__proto__' ); // The Object inherited by `myObject` is not an "own property:"
> false
Check your understanding
Why should you avoid using __proto__
?