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 オブジェクトに設定しています。これにより、childparent のメソッドを継承します。

カスタムプロトタイプチェーンの作成

編集

以下のプログラムは、__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."

このプログラムでは、animaldogspot という継承チェーンを作成しています。spotdog のメソッドと 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__ を使用して配列のプロトタイプチェーンを辿っています。myArrayArray.prototypeObject.prototypenull という継承チェーンが確認できます。

注意点

編集
  • 非推奨: __proto__ は非推奨のプロパティであり、代わりに Object.getPrototypeOf()Object.setPrototypeOf() の使用が推奨されています。
  • パフォーマンス: __proto__ を使用したプロトタイプの変更は、JavaScriptエンジンの最適化を無効にする可能性があり、パフォーマンスに悪影響を及ぼす場合があります。
  • 循環参照: プロトタイプチェーンに循環参照を作成すると、無限ループが発生する可能性があります。
  • プリミティブ値: プリミティブ値(nullundefined、数値、文字列、論理値)の __proto__ プロパティを設定することはできません。
  • 互換性: すべてのJavaScript環境がこのプロパティをサポートしているわけではありません。

脚註

編集
  1. ^ このプロパティは非推奨であり、代わりに Object.getPrototypeOf()Object.setPrototypeOf() の使用が推奨されています。

外部リンク

編集