Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

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

はじめに

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

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?