Prototyp-Übernahme

Wie bei anderen Datentypen ist auch -Objekt Eigenschaften und Methoden aus einem integrierten Object-Prototyp übernimmt. Das heißt, das Objekt enthält sowohl die von Ihnen definierten Eigenschaften als auch „prototyp“-Eigenschaft mit den vom Prototyp übernommenen Methoden:

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

Der direkte Zugriff auf Prototyp-Properties ist nicht über den Property-Schlüssel vorgesehen. Als Wie Sie im vorherigen Beispiel vielleicht feststellen, wird dies durch das [[prototype]] impliziert. oder <prototype>-Notation verwendet wird, Entwicklerkonsolen und Quellen für den Eigenschaftsschlüssel des Prototyps:

// Chrome:
let emptyObject = {};

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

emptyObject;
> Object {  }
  <prototype>: Object { … }

Obwohl alle gängigen Browser __proto__ als De-facto-Standard verwenden, ist dies formell standardisiert und sollte im Produktionscode vermieden werden.

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

Stattdessen können Sie direkt auf das [[Prototype]] eines Objekts zugreifen und es ändern. mit den integrierten Object.getPrototypeOf() und Object.setPrototypeOf() Methoden:

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 }

Um zwischen übernommenen und vom Autor definierten Eigenschaften zu unterscheiden, wird in der Regel als „eigene Eigenschaften“ des Objekts bezeichnet.

Die integrierte Methode Object.hasOwn() gibt true zurück, wenn das angegebene Attribut ist eine direkte Eigenschaft des Objekts und false, wenn die Eigenschaft übernommen wird oder existiert nicht. Verwenden Sie nach Möglichkeit Object.hasOwn(). anstelle der übernommenen Methode hasOwnProperty(), da diese 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

Wissen testen

Warum sollten Sie __proto__ nicht verwenden?

Es ist nicht standardisiert.
Sie wird von vielen Browsern nicht unterstützt.
Dies wird zukünftige Betreuer Ihres Codes verwirren.