Object.getPrototypeOf()

  • Revision slug: JavaScript/Reference/Global_Objects/Object/GetPrototypeOf
  • Revision title: GetPrototypeOf
  • Revision id: 327159
  • Created:
  • Creator: Robg1
  • Is current revision? No
  • Comment Clarify "prototype" and [[Protoype]]

Revision Content

{{ js_minversion_header("1.8.1") }}

Summary

Returns the prototype (i.e. the internal [[Prototype]]) of the specified object.

Method of Object
Implemented in JavaScript 1.8.1
ECMAScript Edition ECMAScript 5th Edition

Syntax

Object.getPrototypeOf(object)

Parameters

object
The object whose prototype is to be returned.

Description

Throws a TypeError exception if the object parameter isn't an Object.

Notes

Object.getPrototypeOf() is the standard implementation of the old and deprecated object.__proto__ property. However it is a read-only method. Actually it is not possible to change the prototype of an instance without using the __proto__ property.
There is a proposal to implement a new Object.setPrototypeOf(object, prototype) method to the standards (see ECMAScript bug 264). It will be something like the following:

Object.setPrototypeOf = function (obj, proto) {
  obj.__proto__ = proto;
};

A combination of Object.getPrototypeOf() and object.__proto__ (since there is not a Object.setPrototypeOf() method) allows to append a whole prototype chain to a new prototype object:

/**
*** Object.setPrototypeOf(@object, @prototype)
* Changes the prototype of an instance
*
**/
 
Object.setPrototypeOf = function (oInstance, oProto) {
  oInstance.__proto__ = oProto;
};
 
/**
*** Object.appendChain(@object, @prototype)
*
* Appends the first non-native prototype of a chain to a new prototype.
* Returns @object (if it was a primitive value it will transformed into an object).
*
*** Object.appendChain(@object [, "@arg_name_1", "@arg_name_2", "@arg_name_3", "..."], "@function_body")
*** Object.appendChain(@object [, "@arg_name_1, @arg_name_2, @arg_name_3, ..."], "@function_body")
*
* Appends the first non-native prototype of a chain to the native Function.prototype object, then appends a
* new Function(["@arg"(s)], "@function_body") to that chain.
* Returns the function.
*
**/

Object.appendChain = function (oChain, oProto) {
  if (arguments.length < 2) { throw new TypeError("Object.appendChain - Not enough arguments"); }
  if (typeof oProto === "number" || typeof oProto === "boolean") { throw new TypeError("second argument to Object.appendChain must be an object or a string"); }

  var oNewProto = oProto, oReturn = o2nd = oLast = oChain instanceof this ? oChain : new oChain.constructor(oChain);

  for (var o1st = this.getPrototypeOf(o2nd); o1st !== Object.prototype && o1st !== Function.prototype; o1st = this.getPrototypeOf(o2nd)) {
    o2nd = o1st;
  }

  if (oProto.constructor === String) {
    oNewProto = Function.prototype;
    oReturn = Function.apply(null, Array.prototype.slice.call(arguments, 1));
    this.setPrototypeOf(oReturn, oLast);
  }

  this.setPrototypeOf(o2nd, oNewProto);
  return oReturn;
}

/**************** USAGE ****************/

// First example: appending a chain to a prototype

function Mammal () {
  this.isMammal = "yes";
}

function MammalSpecies (sMammalSpecies) {
  this.species = sMammalSpecies;
}

MammalSpecies.prototype = new Mammal();
MammalSpecies.prototype.constructor = MammalSpecies;

var oCat = new MammalSpecies("Felis");

alert(oCat.isMammal); // "yes"

function Animal () {
  this.breathing = "yes";
}

Object.appendChain(oCat, new Animal());

alert(oCat.breathing); // "yes"

// Second example: transforming a primitive value into an instance of its constructor and append its chain to a prototype

function Symbol () {
  this.isSymbol = "yes";
}

var nPrime = 17;

alert(typeof nPrime); // "number"

var oPrime = Object.appendChain(nPrime, new Symbol());

alert(oPrime); // "17"
alert(oPrime.isSymbol); // "yes"
alert(typeof oPrime); // "object"

// Third example: appending a chain to the Function.prototype object and appending a new function to that chain

function Person (sName) {
  this.identity = sName;
}

var george = Object.appendChain(new Person("George"), "alert(\"Hello guys!!\");");

alert(george.identity); // "George"
george(); // "Hello guys!!"

Cross-browser compatibility

Based on Kangax's compat table.

{{ CompatibilityTable() }}

Feature Firefox (Gecko) Chrome Internet Explorer Opera Safari
Basic support 3.5 5 9 {{ CompatNo() }} 5
Feature Firefox Mobile (Gecko) Android IE Mobile Opera Mobile Safari Mobile
Basic support {{ CompatUnknown() }} {{ CompatUnknown() }} {{ CompatUnknown() }} {{ CompatUnknown() }} {{ CompatUnknown() }}

Even if Opera does not support Object.getPrototypeOf() yet, it does support the non-standard __proto__ property since Opera 10.50.

See also

{{ languages( { "ja": "ja/JavaScript/Reference/Global_Objects/Object/GetPrototypeOf","zh-cn": "zh-cn/JavaScript/Reference/Global_Objects/Object/GetPrototypeOf" } ) }}

Revision Source

<p>{{ js_minversion_header("1.8.1") }}</p>
<h2 id="Summary" name="Summary">Summary</h2>
<p>Returns the prototype (i.e. the internal <code>[[Prototype]]</code>) of the specified object.</p>
<table class="standard-table">
  <thead>
    <tr>
      <th class="header" colspan="2">Method of <a href="/en/JavaScript/Reference/Global_Objects/Object" title="en/JavaScript/Reference/Global_Objects/Object"><code>Object</code></a></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Implemented in</td>
      <td>JavaScript 1.8.1</td>
    </tr>
    <tr>
      <td>ECMAScript Edition</td>
      <td>ECMAScript 5th Edition</td>
    </tr>
  </tbody>
</table>
<h2 id="Syntax" name="Syntax">Syntax</h2>
<p><code>Object.getPrototypeOf(<em>object</em>)</code></p>
<h2 id="Parameters" name="Parameters">Parameters</h2>
<dl>
  <dt>
    object</dt>
  <dd>
    The object whose prototype is to be returned.</dd>
</dl>
<h2 id="Description" name="Description">Description</h2>
<p><code><span style="font-family: Verdana,Tahoma,sans-serif;">Throws a </span><a href="/en/JavaScript/Reference/Global_Objects/TypeError" title="en/JavaScript/Reference/Global Objects/TypeError"><span style="font-family: Courier New;">TypeError</span></a></code><code><span style="font-family: Verdana,Tahoma,sans-serif;"> exception if the object parameter isn't an </span></code><span style="font-family: Courier New;">Object</span>.</p>
<h2 id="Notes">Notes</h2>
<p><code>Object.getPrototypeOf()</code> is the standard implementation of the old and deprecated <a href="en-US/docs/JavaScript/Reference/Global_Objects/Object/proto" title="en-US/docs/JavaScript/Reference/Global_Objects/Object/proto"><code><em>object</em>.__proto__</code></a> property. However it is a read-only method. <strong>Actually it is not possible to change the prototype of an instance without using the <code>__proto__</code> property.</strong><br />
  There is a proposal to implement a new <code>Object.setPrototypeOf(<em>object</em>, <em>prototype</em>)</code> method to the standards (see <a class="external" href="https://bugs.ecmascript.org/show_bug.cgi?id=264">ECMAScript bug 264</a>). It will be something like the following:</p>
<pre class="brush: js">
Object.setPrototypeOf = function (obj, proto) {
  obj.__proto__ = proto;
};</pre>
<p>A combination of <code>Object.getPrototypeOf()</code> and <a href="en-US/docs/JavaScript/Reference/Global_Objects/Object/proto" title="en-US/docs/JavaScript/Reference/Global_Objects/Object/proto"><code><em>object</em>.__proto__</code></a> (since there is not a <code>Object.setPrototypeOf()</code> method) allows to append a whole prototype chain to a new prototype object:</p>
<div style="height: 600px; overflow: auto; margin-bottom: 12px;">
  <pre class="brush: js">
/**
*** Object.setPrototypeOf(@object, @prototype)
* Changes the prototype of an instance
*
**/
&nbsp;
Object.setPrototypeOf = function (oInstance, oProto) {
&nbsp; oInstance.__proto__ = oProto;
};
&nbsp;
/**
*** Object.appendChain(@object, @prototype)
*
* Appends the first non-native prototype of a chain to a new prototype.
* Returns @object (if it was a primitive value it will transformed into an object).
*
*** Object.appendChain(@object [, "@arg_name_1", "@arg_name_2", "@arg_name_3", "..."], "@function_body")
*** Object.appendChain(@object [, "@arg_name_1, @arg_name_2, @arg_name_3, ..."], "@function_body")
*
* Appends the first non-native prototype of a chain to the native Function.prototype object, then appends a
* new Function(["@arg"(s)], "@function_body") to that chain.
* Returns the function.
*
**/

Object.appendChain = function (oChain, oProto) {
&nbsp; if (arguments.length &lt; 2) { throw new TypeError("Object.appendChain - Not enough arguments"); }
&nbsp; if (typeof oProto === "number" || typeof oProto === "boolean") { throw new TypeError("second argument to Object.appendChain must be an object or a string"); }

&nbsp; var oNewProto = oProto, oReturn = o2nd = oLast = oChain instanceof this ? oChain : new oChain.constructor(oChain);

&nbsp; for (var o1st = this.getPrototypeOf(o2nd); o1st !== Object.prototype &amp;&amp; o1st !== Function.prototype; o1st = this.getPrototypeOf(o2nd)) {
&nbsp;&nbsp;&nbsp; o2nd = o1st;
&nbsp; }

&nbsp; if (oProto.constructor === String) {
&nbsp;&nbsp;&nbsp; oNewProto = Function.prototype;
&nbsp;&nbsp;&nbsp; oReturn = Function.apply(null, Array.prototype.slice.call(arguments, 1));
&nbsp;&nbsp;&nbsp; this.setPrototypeOf(oReturn, oLast);
&nbsp; }

&nbsp; this.setPrototypeOf(o2nd, oNewProto);
&nbsp; return oReturn;
}

/**************** USAGE ****************/

// First example: appending a chain to a prototype

function Mammal () {
&nbsp; this.isMammal = "yes";
}

function MammalSpecies (sMammalSpecies) {
&nbsp; this.species = sMammalSpecies;
}

MammalSpecies.prototype = new Mammal();
MammalSpecies.prototype.constructor = MammalSpecies;

var oCat = new MammalSpecies("Felis");

alert(oCat.isMammal); // "yes"

function Animal () {
&nbsp; this.breathing = "yes";
}

Object.appendChain(oCat, new Animal());

alert(oCat.breathing); // "yes"

// Second example: transforming a primitive value into an instance of its constructor and append its chain to a prototype

function Symbol () {
&nbsp; this.isSymbol = "yes";
}

var nPrime = 17;

alert(typeof nPrime); // "number"

var oPrime = Object.appendChain(nPrime, new Symbol());

alert(oPrime); // "17"
alert(oPrime.isSymbol); // "yes"
alert(typeof oPrime); // "object"

// Third example: appending a chain to the Function.prototype object and appending a new function to that chain

function Person (sName) {
&nbsp; this.identity = sName;
}

var george = Object.appendChain(new Person("George"), "alert(\"Hello guys!!\");");

alert(george.identity); // "George"
george(); // "Hello guys!!"</pre>
</div>
<h2 id="Cross-browser_compatibility">Cross-browser compatibility</h2>
<p>Based on <a class="external" href="http://kangax.github.com/es5-compat-table/">Kangax's compat table</a>.</p>
<p>{{ CompatibilityTable() }}</p>
<div id="compat-desktop">
  <table class="compat-table">
    <tbody>
      <tr>
        <th>Feature</th>
        <th>Firefox (Gecko)</th>
        <th>Chrome</th>
        <th>Internet Explorer</th>
        <th>Opera</th>
        <th>Safari</th>
      </tr>
      <tr>
        <td>Basic support</td>
        <td>3.5</td>
        <td>5</td>
        <td>9</td>
        <td>{{ CompatNo() }}</td>
        <td>5</td>
      </tr>
    </tbody>
  </table>
</div>
<div id="compat-mobile">
  <table class="compat-table">
    <tbody>
      <tr>
        <th>Feature</th>
        <th>Firefox Mobile (Gecko)</th>
        <th>Android</th>
        <th>IE Mobile</th>
        <th>Opera Mobile</th>
        <th>Safari Mobile</th>
      </tr>
      <tr>
        <td>Basic support</td>
        <td>{{ CompatUnknown() }}</td>
        <td>{{ CompatUnknown() }}</td>
        <td>{{ CompatUnknown() }}</td>
        <td>{{ CompatUnknown() }}</td>
        <td>{{ CompatUnknown() }}</td>
      </tr>
    </tbody>
  </table>
</div>
<p>Even if Opera does not support <code>Object.getPrototypeOf()</code> yet, it does support the non-standard <code>__proto__</code> property since Opera 10.50.</p>
<h2 id="See_also" name="See_also">See also</h2>
<ul>
  <li><a class="internal" href="/en/JavaScript/Reference/Global_Objects/Object/isPrototypeOf" title="En/Core JavaScript 1.5 Reference/Global Objects/Object/IsPrototypeOf">isPrototypeOf</a></li>
  <li>John&nbsp;Resig's post on <a class="external" href="http://ejohn.org/blog/objectgetprototypeof/" title="http://ejohn.org/blog/objectgetprototypeof/">getPrototypeOf</a></li>
</ul>
<p>{{ languages( { "ja": "ja/JavaScript/Reference/Global_Objects/Object/GetPrototypeOf","zh-cn": "zh-cn/JavaScript/Reference/Global_Objects/Object/GetPrototypeOf" } ) }}</p>
Revert to this revision