Object.create()

Object.create() メソッドは、指定したプロトタイプオブジェクトおよびプロパティを持つ、新たなオブジェクトを生成します。

構文

Object.create(proto [, propertiesObject ])

引数

proto
新たに生成されるオブジェクトのプロトタイプになるべきオブジェクトです。
propertiesObject
省略可能。指定されていて、 undefined でない場合、それ自身が所有する一連の列挙可能なプロパティ ( own property — つまり、それ自身に定義されていて、プロトタイプチェインの中では 列挙可能でない プロパティ) が、それらのプロパティ名を伴う一連のプロパティ記述子を指定し、新たに生成されるオブジェクトに追加されることになります。これらのプロパティは、 Object.defineProperties() の2番目の引数に対応するものです。

戻り値

指定したプロトタイプオブジェクトとプロパティを持つ新しいオブジェクトです。

例外

proto 引数が null かオブジェクトではない場合、 TypeError 例外が発生します。

Object.create() を用いた古典的な継承

以下の例は、古典的な継承をするための Object.create() の使用方法です。これは、すべての JavaScript がサポートしている単一継承です。

// 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();

console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle);// true
console.log('Is rect an instance of Shape?', rect instanceof Shape);// true
rect.move(1, 1); // Outputs, 'Shape moved.'

複数オブジェクトから継承する場合、ミックスインが可能です。

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

MyClass.prototype = Object.create(SuperClass.prototype); // inherit
mixin(MyClass.prototype, OtherSuperClass.prototype); // mixin

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

mixin 関数は、スーパークラスのプロトタイプをサブクラスのプロトタイプにコピーできます。mixin 関数はユーザーが提供する必要があります。関数のようなミックスインの例は、jQuery.extend() です。

Object.create() と一緒に propertiesObject 引数を使用する

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); }
/* with ES5 Accessors our code can look like this
    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 add a 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

このポリフィルは、プロトタイプは選択されたが第 2 引数を考慮しない状況向けに、新規オブジェクトを生成する主要な利用法に対応します。

実際の ES5 の Object.create では、[[Prototype]] として null を設定することがサポートされていますが、このポリフィルは ECMAScript5 以前のサポートをする制約上、null を使用できないことに注意してください。

if (typeof Object.create != 'function') {
  Object.create = (function(undefined) {
    var Temp = function() {};
    return function (prototype, propertiesObject) {
      if(prototype !== Object(prototype) && prototype !== null) {
        throw TypeError('Argument must be an object, or null');
      }
      Temp.prototype = prototype || {};
      var result = new Temp();
      Temp.prototype = null;
      if (propertiesObject !== undefined) {
        Object.defineProperties(result, propertiesObject); 
      } 
      
      // to imitate the case of Object.create(null)
      if(prototype === null) {
         result.__proto__ = null;
      } 
      return result;
    };
  })();
}

仕様

仕様 ステータス コメント
ECMAScript 5.1 (ECMA-262)
Object.create の定義
標準 初期定義。JavaScript 1.8.5 で実装。
ECMAScript 2015 (6th Edition, ECMA-262)
Object.create の定義
標準  
ECMAScript 2017 Draft (ECMA-262)
Object.create の定義
ドラフト  

ブラウザの互換性

機能 Chrome Firefox (Gecko) Internet Explorer Opera Safari
基本サポート 5 4.0 (2) 9 11.60 5
機能 Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
基本サポート (有) (有) 4.0 (2) (有) 11.5 (有)

関連情報

ドキュメントのタグと貢献者

 このページの貢献者: YuichiNukiyama, teoli, mokeke, ethertank, yyss
 最終更新者: YuichiNukiyama,