mozilla

Revision 462273 of Object.getPrototypeOf()

  • Revision slug: Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf
  • Revision title: Object.getPrototypeOf
  • Revision id: 462273
  • Created:
  • Creator: Teppeis
  • Is current revision? No
  • Comment

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 12.10 (maybe earlier) 5
Feature Firefox Mobile (Gecko) Android IE Mobile Opera Mobile Safari Mobile
Basic support {{CompatUnknown}} {{CompatUnknown}} {{CompatUnknown}} {{CompatUnknown}} {{CompatUnknown}}

Even though older Opera versions don't support Object.getPrototypeOf() yet, they do support the non-standard __proto__ property since Opera 10.50.

See also

Revision Source

<div>
  {{js_minversion_header("1.8.1")}}</div>
<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-US/docs/JavaScript/Reference/Global_Objects/Object" title="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>
<pre class="syntaxbox">
<code>Object.getPrototypeOf(<em>object</em>)</code></pre>
<h3 id="Parameters" name="Parameters">Parameters</h3>
<dl>
  <dt>
    object</dt>
  <dd>
    The object whose prototype is to be returned.</dd>
</dl>
<h2 id="Description" name="Description">Description</h2>
<p>Throws a <a href="/en-US/docs/JavaScript/Reference/Global_Objects/TypeError" title="JavaScript/Reference/Global Objects/TypeError"><code>TypeError</code></a> exception if the object parameter isn't an <code>Object</code>.</p>
<h2 id="Notes" name="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="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="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
*
**/

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 &lt; 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 &amp;&amp; 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!!"</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>12.10 (maybe earlier)</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 though older Opera versions don't support <code>Object.getPrototypeOf()</code> yet, they do 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 href="/en-US/docs/JavaScript/Reference/Global_Objects/Object/isPrototypeOf" title="JavaScript/Reference/Global Objects/Object/IsPrototypeOf">isPrototypeOf</a></li>
  <li>John Resig's post on <a class="external" href="http://ejohn.org/blog/objectgetprototypeof/" title="http://ejohn.org/blog/objectgetprototypeof/">getPrototypeOf</a></li>
</ul>
Revert to this revision