mozilla

Revision 644991 of Object.create()

  • Revision slug: Web/JavaScript/Reference/Global_Objects/Object/create
  • Revision title: Object.create()
  • Revision id: 644991
  • Created:
  • Creator: shybloo
  • Is current revision? No
  • Comment Small fixes

Revision Content

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

Summary

The Object.create() method creates a new object with the specified prototype object and properties.

Syntax

Object.create(proto [, propertiesObject ])

Parameters

proto
The object which should be the prototype of the newly-created object.
propertiesObject
If specified and not undefined, an object whose enumerable own properties (that is, those properties defined upon itself and not enumerable properties along its prototype chain) specify property descriptors to be added to the newly-created object, with the corresponding property names. These properties correspond to the second argument of {{jsxref("Object.defineProperties")}}.

Throws

Throws a {{jsxref("Global_Objects/TypeError", "TypeError")}} exception if the proto parameter isn't null or an object.

Examples

Classical inheritance with Object.create

Below is an example of how to use Object.create to achieve classical inheritance. This is for single inheritance, which is all that Javascript supports.

// Shape - superclass
function Shape() {
  this.x = 0;
  this.y = 0;
}

// superclass method
Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
    console.info("Shape moved.");
};

// Rectangle - subclass
function Rectangle() {
  Shape.call(this); // call super constructor.
}

// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();

rect instanceof Rectangle // true.
rect instanceof Shape // true.

rect.move(1, 1); // Outputs, "Shape moved."

If you wish to inherit from multiple objects, then mixins are a possibility.

function MyClass() {
     SuperClass.call(this);
     OtherSuperClass.call(this);
}

MyClass.prototype = Object.create(SuperClass.prototype); // inherit
MyClass.prototype.constructor = MyClass; // hand back the constructor
mixin(MyClass.prototype, OtherSuperClass.prototype); // mixin

MyClass.prototype.myMethod = function() {
     // do a thing
};

The mixin function would copy the functions from the superclass prototype to the subclass prototype, the mixin function needs to be supplied by the user. An example of a mixin like function would be jQuery.extend.

Using <propertiesObject> argument with Object.create

var o;

// create an object with null as prototype
o = Object.create(null);


o = {};
// is equivalent to:
o = Object.create(Object.prototype);


// Example where we create an object with a couple of sample properties.
// (Note that the second parameter maps keys to *property descriptors*.)
o = Object.create(Object.prototype, {
  // foo is a regular "value property"
  foo: { writable:true, configurable:true, value: "hello" },
  // bar is a getter-and-setter (accessor) property
  bar: {
    configurable: false,
    get: function() { return 10 },
    set: function(value) { console.log("Setting `o.bar` to", value) }
}});


function Constructor(){}
o = new Constructor();
// is equivalent to:
o = Object.create(Constructor.prototype);
// Of course, if there is actual initialization code in the
// Constructor function, the Object.create cannot reflect it


// create a new object whose prototype is a new, empty object
// and a adding single property 'p', with value 42
o = Object.create({}, { p: { value: 42 } })

// by default properties ARE NOT writable, enumerable or configurable:
o.p = 24
o.p
// 42

o.q = 12
for (var prop in o) {
   console.log(prop)
}
// "q"

delete o.p
// false

// to specify an ES3 property
o2 = Object.create({}, { p: {
      value: 42,
      writable: true,
      enumerable: true,
      configurable: true }
});

Polyfill

This polyfill covers the main use case which is creating a new object for which the prototype has been chosen but doesn't take the second argument into account.

if (typeof Object.create != 'function') {
    (function () {
        var F = function () {};
        Object.create = function (o) {
            if (arguments.length > 1) { 
              throw Error('Second argument not supported');
            }
            if (o === null) { 
              throw Error('Cannot set a null [[Prototype]]');
            }
            if (typeof o != 'object') { 
              throw TypeError('Argument must be an object');
            }
            F.prototype = o;
            return new F();
        };
    })();
}

Specifications

Specification Status Comment
{{SpecName('ES5.1', '#sec-15.2.3.5', 'Object.create')}} {{Spec2('ES5.1')}} Initial definition. Implemented in JavaScript 1.8.5
{{SpecName('ES6', '#sec-object.create', 'Object.create')}} {{Spec2('ES6')}}  

Browser compatibility

{{ CompatibilityTable() }}

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support 5 {{ CompatGeckoDesktop("2") }} 9 11.60 5
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support {{ CompatVersionUnknown() }} {{ CompatVersionUnknown() }} {{ CompatGeckoDesktop("2") }} {{ CompatVersionUnknown() }} 11.50 {{ CompatVersionUnknown() }}

Based on Kangax's compat table.

See also

  • {{jsxref("Object.defineProperty")}}
  • {{jsxref("Object.defineProperties")}}
  • {{jsxref("Object.prototype.isPrototypeOf")}}
  • John Resig's post on getPrototypeOf

Revision Source

<div>
 {{JSRef("Global_Objects", "Object")}}</div>
<h2 id="Summary" name="Summary">Summary</h2>
<p>The <code><strong>Object.create()</strong></code> method creates a new object with the specified prototype object and properties.</p>
<h2 id="Syntax" name="Syntax">Syntax</h2>
<pre class="syntaxbox">
<code>Object.create(<em>proto</em> [, <em>propertiesObject</em> ])</code></pre>
<h3 id="Parameters" name="Parameters">Parameters</h3>
<dl>
 <dt>
  proto</dt>
 <dd>
  The object which should be the prototype of the newly-created object.</dd>
 <dt>
  propertiesObject</dt>
 <dd>
  If specified and not undefined, an object whose enumerable own properties (that is, those properties defined upon itself and <em>not</em> enumerable properties along its prototype chain) specify property descriptors to be added to the newly-created object, with the corresponding property names. These properties correspond to the second argument of {{jsxref("Object.defineProperties")}}<code>.</code></dd>
</dl>
<h3 id="Description" name="Description">Throws</h3>
<p>Throws a {{jsxref("Global_Objects/TypeError", "TypeError")}} exception if the proto parameter isn't null or an object.</p>
<h2 id="Examples" name="Examples">Examples</h2>
<h3 id="Classical_inheritance_with_Object.create">Classical inheritance with <code>Object.create</code></h3>
<p>Below is an example of how to use Object.create to achieve classical inheritance. This is for single inheritance, which is all that Javascript supports.</p>
<div class="highlight">
 <pre class="brush: js">
// Shape - superclass
function Shape() {
  this.x = 0;
  this.y = 0;
}

// superclass method
Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
    console.info("Shape moved.");
};

// Rectangle - subclass
function Rectangle() {
  Shape.call(this); // call super constructor.
}

// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();

rect instanceof Rectangle // true.
rect instanceof Shape // true.

rect.move(1, 1); // Outputs, "Shape moved."
</pre>
</div>
<p>If you wish to inherit from multiple objects, then mixins are a possibility.</p>
<div class="highlight">
 <pre class="brush: js">
function MyClass() {
     SuperClass.call(this);
     OtherSuperClass.call(this);
}

MyClass.prototype = Object.create(SuperClass.prototype); // inherit
MyClass.prototype.constructor = MyClass; // hand back the constructor
mixin(MyClass.prototype, OtherSuperClass.prototype); // mixin

MyClass.prototype.myMethod = function() {
     // do a thing
};
</pre>
</div>
<p>The mixin function would copy the functions from the superclass prototype to the subclass prototype, the mixin function needs to be supplied by the user. An example of a mixin like function would be <a href="http://api.jquery.com/jQuery.extend/" title="http://api.jquery.com/jQuery.extend/">jQuery.extend</a>.</p>
<h3 id="Using_&lt;propertiesObject&gt;_argument_with_Object.create">Using &lt;propertiesObject&gt; argument with <code>Object.create</code></h3>
<pre class="brush: js">
var o;

// create an object with null as prototype
o = Object.create(null);


o = {};
// is equivalent to:
o = Object.create(Object.prototype);


// Example where we create an object with a couple of sample properties.
// (Note that the second parameter maps keys to *property descriptors*.)
o = Object.create(Object.prototype, {
  // foo is a regular "value property"
  foo: { writable:true, configurable:true, value: "hello" },
  // bar is a getter-and-setter (accessor) property
  bar: {
    configurable: false,
    get: function() { return 10 },
    set: function(value) { console.log("Setting `o.bar` to", value) }
}});


function Constructor(){}
o = new Constructor();
// is equivalent to:
o = Object.create(Constructor.prototype);
// Of course, if there is actual initialization code in the
// Constructor function, the Object.create cannot reflect it


// create a new object whose prototype is a new, empty object
// and a adding single property 'p', with value 42
o = Object.create({}, { p: { value: 42 } })

// by default properties ARE NOT writable, enumerable or configurable:
o.p = 24
o.p
// 42

o.q = 12
for (var prop in o) {
   console.log(prop)
}
// "q"

delete o.p
// false

// to specify an ES3 property
o2 = Object.create({}, { p: {
      value: 42,
      writable: true,
      enumerable: true,
      configurable: true }
});
</pre>
<h2 id="Polyfill">Polyfill</h2>
<p>This polyfill covers the main use case which is creating a new object for which the prototype has been chosen but doesn't take the second argument into account.</p>
<pre class="brush: js">
if (typeof Object.create != 'function') {
    (function () {
        var F = function () {};
        Object.create = function (o) {
            if (arguments.length &gt; 1) { 
              throw Error('Second argument not supported');
            }
            if (o === null) { 
              throw Error('Cannot set a null [[Prototype]]');
            }
            if (typeof o != 'object') { 
              throw TypeError('Argument must be an object');
            }
            F.prototype = o;
            return new F();
        };
    })();
}</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('ES5.1', '#sec-15.2.3.5', 'Object.create')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td>Initial definition. Implemented in JavaScript 1.8.5</td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-object.create', 'Object.create')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td>&nbsp;</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>5</td>
    <td>{{ CompatGeckoDesktop("2") }}</td>
    <td>9</td>
    <td>11.60</td>
    <td>5</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>{{ CompatVersionUnknown() }}</td>
    <td>{{ CompatVersionUnknown() }}</td>
    <td>{{ CompatGeckoDesktop("2") }}</td>
    <td>{{ CompatVersionUnknown() }}</td>
    <td>11.50</td>
    <td>{{ CompatVersionUnknown() }}</td>
   </tr>
  </tbody>
 </table>
</div>
<p>Based on Kangax's compat table.</p>
<h2 id="See_also" name="See_also">See also</h2>
<ul>
 <li>{{jsxref("Object.defineProperty")}}</li>
 <li>{{jsxref("Object.defineProperties")}}</li>
 <li>{{jsxref("Object.prototype.isPrototypeOf")}}</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