LoginSignup
1
0

More than 5 years have passed since last update.

Object.getPrototypeOf(obj) は obj.constructor.prototype と同義か?

Last updated at Posted at 2016-11-15

はじめに

Effective JavaScript を読み返していると、項目 31 で覚えておくべき事項として以下が紹介されていました。

非標準の __proto__ プロパティよりも、標準に準拠した Object.getPrototypeOf が好ましい。

なるほど Object.getPrototypeOf() があるのか :innocent:

ここで「Object.getPrototypeOf()obj.constructor.prototype では代用できないだろうか」という疑問が湧きました。そこで調べてみると、StackOverflow に is Object.getPrototypeOf() same as Object.constructor.prototype in Javascript? というまさしく求めていた記事を発見しました。そこで、その記事の内容を整理して共有したいと思います。

追記 (2016/11/16 (水))

__proto__ プロパティは標準化されていると @mysticatea 様にご指摘頂きました。ありがとうございます :bow:

確かに MDN の Object.prototype.__proto__ にも

__proto__ プロパティはECMAScript第6版言語仕様で標準化されました。そして、将来にサポートされます。

と言及されていますね。ただし、パフォーマンス上の観点から、やはり使用は推奨されていないようです。

概要

先にタイトルの答えを発表すると NO :no_good: です。

例えば Object.create() で引数に null を渡してオブジェクトを生成したとします。これは prototypenull としてオブジェクトを生成するということです。この場合 obj.constructorundefined となるため obj.constructor.prototype を取得することはできません。

let obj1 = Object.create(null);

obj1.constructor; // undefined

一方 Object.getPrototypeOf() メソッドは null を返します。

Object.getPrototypeOf(obj1); // null

prototypenull の場合でも利用できるのは便利ですね。

対して、一般的なオブジェクト (prototype として Object.prototype を持つオブジェクト) の場合は一致します。

let obj2 = {};

Object.getPrototypeOf(obj2); // Object.prototype
obj.constructor.prototype; // Object.prototype

Object.getPrototypeOf(obj2) === obj.constructor.prototype; // true

なお Object.create(null) で生成したオブジェクトについても、手動で prototypeObject.prototype 設定すれば、一般的なオブジェクトの場合と同じ挙動になります。

let obj3 = Object.create(null);
Object.setPrototypeOf(obj3, Object.prototype);

obj3.constructor.prototype; // Object.prototype
Object.getPrototypeOf(obj3); // Object.prototype

obj3.constructor.prototype === Object.getPrototypeOf(obj3); // true

なお Object.setPrototypeOf() は ECMAScript 6 のメソッドです。

追記 (2016/11/16 (水))

@mysticatea 様より

obj.constructorは書き換え可能なプロパティであるため、本当にobjのコンストラクタを指しているとは限りません。

とのご指摘を頂きました。ありがとうございます :bow:

確かに、このことも Object.getPrototypeOf(obj)obj.constructor.prototype の大きな差異ですね。

function PseudoObject() {};
PseudoObject.prototype = {};

let obj4 = new PseudoObject();

obj4.constructor.prototype; // Object.prototype
Object.getPrototypeOf(obj4); // PseudoObject.prototype

obj4.constructor.prototype === Object.getPrototypeOf(obj4); // false

参考

1
0
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0