Revision 496391 of Object.setPrototypeOf()

  • Revision slug: Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf
  • Revision title: Object.setPrototypeOf()
  • Revision id: 496391
  • Created:
  • Creator: fscholz
  • Is current revision? No
  • Comment

Revision Content

{{JSRef("Global_Objects", "Object")}} {{harmony()}}

Summary

The Object.setPrototype() method sets the prototype (i.e., the internal [[Prototype]] property ) of a specified object to another object or null.

Syntax

Object.setPrototypeOf(obj, prototype)

Parameters

obj
The object which is to have its prototype set.
prototype
The object's new prototype (an object or null).

Description

Throws a {{jsxref("Global_Objects/TypeError", "TypeError")}} exception if the prototype parameter isn't an object or null (i.e., Number, String, Boolean, or undefined).

Object.setPrototypeOf() is in the latest ECMAScript 6 standard draft. The old {{jsxref("Object.proto", "obj.__proto__")}} property is a non-standard property and has been deprecated from the latest ES6 draft, but all the modern browsers (including IE11 preview version) have already implemented it.

Examples

var dict = Object.setPrototypeOf({}, null);

Polyfill

Using the old and deprecated {{jsxref("Object.proto", "obj.__proto__")}} property, we can easily define Object.setPrototypeOf if it isn't available already:

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

Appending a whole prototype chain to a new prototype object

A combination of Object.getPrototypeOf() and {{jsxref("Object.proto", "obj.__proto__")}} 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!!"

Specifications

Specification Status Comment
{{SpecName('ES6', '#sec-object.setprototypeof', 'Object.setProtoypeOf')}} {{Spec2('ES6')}} Initial definition.

Browser compatibility

{{ CompatibilityTable() }}

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support {{ CompatNo() }}
See Issue 2675
{{ CompatNo() }}
See {{bug("885788")}}
{{ CompatNo() }} {{ CompatNo() }} {{ CompatNo() }}
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support {{ CompatNo() }} {{ CompatNo() }} {{ CompatNo() }} {{ CompatNo() }} {{ CompatNo() }} {{ CompatNo() }}

See also

  • {{jsxref("Object.prototype.isPrototypeOf")}}
  • {{jsxref("Object.getPrototypeOf")}}

Revision Source

<div>
 <div>
  {{JSRef("Global_Objects", "Object")}} {{harmony()}}</div>
</div>
<h2 id="Summary" name="Summary">Summary</h2>
<p>The <code><strong>Object.setPrototype()</strong></code> method sets the prototype (i.e., the internal <code>[[Prototype]] </code>property ) of a specified object to another object or null.</p>
<h2 id="Syntax" name="Syntax">Syntax</h2>
<pre class="syntaxbox">
<code>Object.setPrototypeOf(<em>obj, prototype</em>)</code></pre>
<h3 id="Parameters" name="Parameters">Parameters</h3>
<dl>
 <dt>
  obj</dt>
 <dd>
  The object which is to have its prototype set.</dd>
 <dt>
  prototype</dt>
 <dd>
  The object's new prototype (an object or null).</dd>
</dl>
<h2 id="Description" name="Description">Description</h2>
<p>Throws a {{jsxref("Global_Objects/TypeError", "TypeError")}} exception if the prototype parameter isn't an object or null (i.e., Number, String, Boolean, or undefined).</p>
<p><code>Object.setPrototypeOf()</code> is in the latest ECMAScript 6 standard draft. The old {{jsxref("Object.proto", "obj.__proto__")}} property is a non-standard property and has been deprecated from the latest ES6 draft, but all the modern browsers (including IE11 preview version) have already implemented it.</p>
<h2 id="Notes" name="Notes">Examples</h2>
<pre class="brush: js">
var dict = Object.setPrototypeOf({}, null);
</pre>
<h2 id="Notes" name="Notes">Polyfill</h2>
<p>Using the old and deprecated {{jsxref("Object.proto", "obj.__proto__")}} property, we can easily define <code>Object.setPrototypeOf</code>&nbsp;if it isn't available already:</p>
<pre class="brush: js">
Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {
  obj.__proto__ = proto;
  return obj; 
}</pre>
<h3 id="Appending_a_whole_prototype_chain_to_a_new_prototype_object">Appending a whole prototype chain to a new prototype object</h3>
<p>A combination of <code>Object.getPrototypeOf()</code> and {{jsxref("Object.proto", "obj.__proto__")}} allows to append a whole prototype chain to a new prototype object:</p>
<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;
}
</pre>
<h4 id="Usage">Usage</h4>
<pre class="brush: js">
// 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>
<h2 id="Specifications">Specifications</h2>
<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-object.setprototypeof', 'Object.setProtoypeOf')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td>Initial definition.</td>
  </tr>
 </tbody>
</table>
<h2 id="Browser_compatibility">Browser compatibility</h2>
<p>{{ CompatibilityTable() }}</p>
<div id="compat-desktop">
 <table class="compat-table">
  <tbody>
   <tr>
    <th>Feature</th>
    <th>Chrome</th>
    <th>Firefox (Gecko)</th>
    <th>Internet Explorer</th>
    <th>Opera</th>
    <th>Safari</th>
   </tr>
   <tr>
    <td>Basic support</td>
    <td>{{ CompatNo() }}<br />
     See <a href="https://code.google.com/p/v8/issues/detail?id=2675">Issue 2675</a></td>
    <td>{{ CompatNo() }}<br />
     See {{bug("885788")}}</td>
    <td>{{ CompatNo() }}</td>
    <td>{{ CompatNo() }}</td>
    <td>{{ CompatNo() }}</td>
   </tr>
  </tbody>
 </table>
</div>
<div id="compat-mobile">
 <table class="compat-table">
  <tbody>
   <tr>
    <th>Feature</th>
    <th>Android</th>
    <th>Chrome for Android</th>
    <th>Firefox Mobile (Gecko)</th>
    <th>IE Mobile</th>
    <th>Opera Mobile</th>
    <th>Safari Mobile</th>
   </tr>
   <tr>
    <td>Basic support</td>
    <td>{{ CompatNo() }}</td>
    <td>{{ CompatNo() }}</td>
    <td>{{ CompatNo() }}</td>
    <td>{{ CompatNo() }}</td>
    <td>{{ CompatNo() }}</td>
    <td>{{ CompatNo() }}</td>
   </tr>
  </tbody>
 </table>
</div>
<h2 id="See_also" name="See_also">See also</h2>
<ul>
 <li>{{jsxref("Object.prototype.isPrototypeOf")}}</li>
 <li>{{jsxref("Object.getPrototypeOf")}}</li>
</ul>
Revert to this revision