プロトタイプの継承

他のデータ型と同様に、オブジェクトは組み込みの Object プロトタイプからプロパティとメソッドを継承します。つまり、結果として得られるオブジェクトには、定義したプロパティと、そのプロトタイプから継承されたメソッドを含むプロトタイプ プロパティの両方が含まれます。

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]] または <prototype> 表記によるものです。

// Chrome:
let emptyObject = {};

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

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

__proto__ はすべての一般的なブラウザで事実上の標準として使用されていますが、正式に標準化されていないため、本番環境のコードでは使用を避ける必要があります。

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

代わりに、組み込みの Object.getPrototypeOf() メソッドと Object.setPrototypeOf() メソッドを使用して、オブジェクトの [[Prototype]] に直接アクセスして変更できます。

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 }

継承されたプロパティと作成者が定義したプロパティを区別するために、後者は通常、オブジェクトの「独自のプロパティ」と呼ばれます。

組み込みの Object.hasOwn() メソッドは、指定されたプロパティがオブジェクトの直接プロパティである場合は true を返し、プロパティが継承されているか、存在しない場合は false を返します。可能な限り、Object.create() をサポートしていない継承された hasOwnProperty() メソッドの代わりに、Object.hasOwn() を使用してください。

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

理解度をチェックする

__proto__ の使用を避けるべき理由

標準化されていないからです
多くのブラウザではサポートされていません。
今後、コードを管理するユーザーの混乱を招きます。