JavaScript/Object/ proto
Object.prototype.__proto__ はオブジェクトのプロトタイプ(内部の [[Prototype]] プロパティ)を取得または設定するためのアクセサプロパティです。このプロパティを使用すると、オブジェクトの継承元を読み取ったり変更したりすることができます[1]。
構文
編集// ゲッター obj.__proto__ // セッター obj.__proto__ = value
obj: プロトタイプを取得または設定するオブジェクト。value: 設定する新しいプロトタイプオブジェクト。
説明
編集__proto__ アクセサプロパティは、ECMAScript仕様で定義されている内部の [[Prototype]] スロットを露出します。このプロパティを使用することで、オブジェクトのプロトタイプを読み取ったり変更したりすることができますが、パフォーマンスの問題があるため、代わりに Object.getPrototypeOf() と Object.setPrototypeOf() の使用が推奨されています。
例
編集プロトタイプの読み取り
編集以下のプログラムは、__proto__ を使用してオブジェクトのプロトタイプを読み取る方法を示しています。
const obj = {}; console.log(obj.__proto__ === Object.prototype); // true const arr = []; console.log(arr.__proto__ === Array.prototype); // true console.log(arr.__proto__.__proto__ === Object.prototype); // true // 推奨される方法 console.log(Object.getPrototypeOf(obj) === Object.prototype); // true
このプログラムでは、__proto__ を使用して各オブジェクトのプロトタイプを確認しています。配列のプロトタイプチェーンが Array.prototype を経由して Object.prototype につながっていることも確認できます。
プロトタイプの設定
編集以下のプログラムは、__proto__ を使用してオブジェクトのプロトタイプを設定する方法を示しています。
const parent = { greet: function() { return 'Hello from parent'; } }; const child = { name: 'Child Object' }; // __proto__ を使用してプロトタイプを設定 child.__proto__ = parent; console.log(child.greet()); // "Hello from parent" // 推奨される方法 const anotherChild = { name: 'Another Child' }; Object.setPrototypeOf(anotherChild, parent); console.log(anotherChild.greet()); // "Hello from parent"
このプログラムでは、__proto__ を使用して child オブジェクトのプロトタイプを parent オブジェクトに設定しています。これにより、child は parent のメソッドを継承します。
カスタムプロトタイプチェーンの作成
編集以下のプログラムは、__proto__ を使用してカスタムプロトタイプチェーンを作成する例を示しています。
const animal = { eat: function() { return <code>${this.name} is eating.</code>; } }; const dog = { bark: function() { return <code>${this.name} says woof!</code>; } }; // dog のプロトタイプを animal に設定 dog.__proto__ = animal; const spot = { name: 'Spot' }; // spot のプロトタイプを dog に設定 spot.__proto__ = dog; console.log(spot.name); // "Spot" console.log(spot.bark()); // "Spot says woof!" console.log(spot.eat()); // "Spot is eating."
このプログラムでは、animal → dog → spot という継承チェーンを作成しています。spot は dog のメソッドと animal のメソッドの両方を継承します。
プロトタイプチェーンの複数レベルへのアクセス
編集以下のプログラムは、__proto__ を使用してプロトタイプチェーンの複数レベルにアクセスする方法を示しています。
// 継承チェーン: myArray → Array.prototype → Object.prototype const myArray = [1, 2, 3]; // Array.prototype のメソッドにアクセス console.log(myArray.join('-')); // "1-2-3" // Array.prototype.__proto__ は Object.prototype console.log(myArray.__proto__ === Array.prototype); // true console.log(myArray.__proto__.__proto__ === Object.prototype); // true // Object.prototype のメソッドにアクセス console.log(myArray.hasOwnProperty('length')); // true // Object.prototype.__proto__ は null console.log(myArray.__proto__.__proto__.__proto__ === null); // true
このプログラムでは、__proto__ を使用して配列のプロトタイプチェーンを辿っています。myArray → Array.prototype → Object.prototype → null という継承チェーンが確認できます。
注意点
編集- 非推奨:
__proto__は非推奨のプロパティであり、代わりにObject.getPrototypeOf()とObject.setPrototypeOf()の使用が推奨されています。 - パフォーマンス:
__proto__を使用したプロトタイプの変更は、JavaScriptエンジンの最適化を無効にする可能性があり、パフォーマンスに悪影響を及ぼす場合があります。 - 循環参照: プロトタイプチェーンに循環参照を作成すると、無限ループが発生する可能性があります。
- プリミティブ値: プリミティブ値(
null、undefined、数値、文字列、論理値)の__proto__プロパティを設定することはできません。 - 互換性: すべてのJavaScript環境がこのプロパティをサポートしているわけではありません。
脚註
編集- ^ このプロパティは非推奨であり、代わりに
Object.getPrototypeOf()とObject.setPrototypeOf()の使用が推奨されています。