JavaScriptの__proto__
の概念は、オブジェクト指向プログラミングにおけるプロトタイプチェーンに関連しています。__proto__
はオブジェクトが別のオブジェクトを参照するための内部リンクであり、オブジェクトがどのプロトタイプを持っているかを示します。しかし、最近のJavaScriptでは、__proto__
が推奨されていないため、代わりにObject.getPrototypeOf()
やObject.setPrototypeOf()
を使用することが推奨されています。
本記事では、__proto__
を使わずにオブジェクトを操作する方法、またその影響を含む、JavaScriptのモデルやオブジェクトのプロトタイプチェーンについて深掘りしていきます。さらに、JavaScriptで__proto__
なしでどのようにプロトタイプを操作できるかを解説します。

1. __proto__
とその役割
まず、__proto__
が何であるかを理解することが重要です。__proto__
は、あるオブジェクトが別のオブジェクトをその「プロトタイプ」として持つためのリンクを提供します。プロトタイプチェーンは、オブジェクトがプロパティやメソッドを検索する際に使われるメカニズムで、最終的にはnull
に到達するまで親オブジェクトを辿ります。
例えば、次のコードは、person
というオブジェクトが__proto__
を使ってanimal
というオブジェクトを参照している例です。
javascriptlet animal = {
eats: true
};
let person = {
name: "John"
};
person.__proto__ = animal;
console.log(person.eats); // true
上記の例では、person
オブジェクトがanimal
オブジェクトをプロトタイプとして設定しています。これにより、person
が持っていないプロパティ(例えばeats
)をanimal
から取得できます。
2. __proto__
の代わりに使うべき方法
現代のJavaScriptでは、__proto__
の使用は非推奨です。代わりに、Object.getPrototypeOf()
やObject.setPrototypeOf()
を使用することで、オブジェクトのプロトタイプを操作できます。これらのメソッドは、プロトタイプチェーンをより明示的に管理できるため、コードの可読性と保守性が向上します。
2.1 Object.getPrototypeOf()
Object.getPrototypeOf()
メソッドは、指定したオブジェクトのプロトタイプ(親オブジェクト)を取得します。
javascriptlet animal = {
eats: true
};
let person = {
name: "John"
};
Object.setPrototypeOf(person, animal);
console.log(Object.getPrototypeOf(person) === animal); // true
このコードでは、person
オブジェクトにanimal
オブジェクトをプロトタイプとして設定した後、Object.getPrototypeOf()
を使ってそのプロトタイプを取得しています。
2.2 Object.setPrototypeOf()
Object.setPrototypeOf()
メソッドは、指定したオブジェクトに新しいプロトタイプを設定します。__proto__
を直接変更する代わりに、このメソッドを使用することで、より明示的にプロトタイプを変更できます。
javascriptlet animal = {
eats: true
};
let person = {
name: "John"
};
Object.setPrototypeOf(person, animal);
console.log(person.eats); // true
上記のコードは、person
オブジェクトにanimal
オブジェクトをプロトタイプとして設定し、person
がanimal
のプロパティ(eats
)にアクセスできることを示しています。
3. __proto__
が存在しないオブジェクト
JavaScriptのオブジェクトは通常、内部的にプロトタイプを持っていますが、Object.create(null)
を使うと、プロトタイプチェーンがまったくないオブジェクトを作成することができます。これにより、__proto__
が存在しないオブジェクトを生成できます。
javascriptlet obj = Object.create(null);
console.log(obj.__proto__); // undefined
このようなオブジェクトは、プロトタイプチェーンを使わない特殊なオブジェクトを作成する場合に便利です。例えば、セキュリティ上の理由から、__proto__
を持たないオブジェクトを作成することで、意図しないプロトタイプ継承を避けることができます。
4. オブジェクトのプロトタイプを変更する影響
プロトタイプチェーンを変更することは強力ですが、注意が必要です。プロトタイプを変更することで、オブジェクトの動作や挙動が予期しない形で変わる可能性があります。特に、大規模なコードベースでプロトタイプを変更すると、後でバグを引き起こす原因となることがあります。
たとえば、プロトタイプの変更によって予期しない副作用が発生する可能性があります。オブジェクトのメソッドやプロパティが上書きされたり、意図しないタイミングで変更が反映されることがあります。そのため、プロトタイプの変更は慎重に行う必要があります。
5. まとめ
__proto__
は、JavaScriptにおけるプロトタイプチェーンを操作するための重要な機能ですが、非推奨となっており、代わりにObject.getPrototypeOf()
やObject.setPrototypeOf()
を使用することが推奨されています。また、Object.create(null)
を使用することで、__proto__
が存在しないオブジェクトを作成することができ、セキュリティや意図しない継承の回避に役立ちます。
プロトタイプチェーンの理解とその管理は、JavaScriptでのオブジェクト指向プログラミングにおいて非常に重要な要素です。プロトタイプを変更する際は、その影響を十分に理解し、慎重に行動することが求められます。