Traducción en curso

El método Object.create() crea un objeto nuevo, utilizando un objeto existente como el prototipo del nuevo objeto creado.

Sintaxis

Object.create(proto[, propertiesObject])

Parámetros

proto
Objeto el cual debe ser el prototipo del nuevo objeto creado.
propertiesObject
Opcional. Si se especifica y no es undefined, un objeto cuyas propiedades enumerables propias (es decir, aquellas propiedades definidas sobre si mismo y no son propiedades enumerable a lo largo de su cadena de prototipos) espefica descriptores de propiedad para ser agregadas al objeto recien creado, con los nombres de propiedad correspondiente. Estas propiedades corresponden al segundo argumento de Object.defineProperties.

Valor devuelto

Un nuevo objeto con el prototipo y propiedades del objeto especificado.

Excepciones

Una excepción TypeError si el parámetro propertiesObject es null o un objeto envolvente no primitivo.

Ejemplos

Herencia clásica con Object.create()

Debajo se encuentra un ejemplo de cómo usar Object.create() para lograr herencia clásica. Este es para herencia simple, la cual es todo lo que soporta JavaScript.

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

// método de la superclase
Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
    console.info("Shape moved.");
};

// Rectangle - subclase
function Rectangle() {
  Shape.call(this); // llama al contructor de la superclase.
}

// subclase extiende superclase
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();

console.log('¿Es rect una instancia de Rectangle?',
  rect instanceof Rectangle); // true
console.log('¿Es rect una instancia de Shape?',
  rect instanceof Shape); // true
rect.move(1, 1); // Imprime, 'Shape moved.'

Si desea heredar desde múltiples objetos, entonces los mixins son una posibilidad.

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

// inherit one class
MyClass.prototype = Object.create(SuperClass.prototype);
// mixin another
Object.assign(MyClass.prototype, OtherSuperClass.prototype);
// re-assign constructor
MyClass.prototype.constructor = MyClass;

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

Object.assign() copia las propiedades del prototipo OtherSuperClass al prototipo de MyClass, haciéndolas disponibles en todas las instancias de MyClass. Object.assign() se introdujo con ES2015 y tiene polyfill. Si el soporte para navegadores antiguos es necesario, se puede utilizar jQuery.extend()_.assign().

Usando el argumento propertiesObject con Object.create()

var o;

// crea un objeto con un prototipo como null
o = Object.create(null);


o = {};
// esto equivale a:
o = Object.create(Object.prototype);


// Ejemplo en donde creamos un objeto con un par de propiedades de ejemplo.
// (Note que el segundo parámetro mapea claves para los *descriptores de propiedad*.)
o = Object.create(Object.prototype, {
  // foo es un habitual "propiedad de valor"
  foo: { writable:true, configurable:true, value: "hello" },
  // bar es una propiedad getter-and-setter (de acceso)
  bar: {
    configurable: false,
    get: function() { return 10 },
    set: function(value) { console.log("Setting `o.bar` to", value) }
}});


function Constructor(){}
o = new Constructor();
// es equivalente a:
o = Object.create(Constructor.prototype);
// Por supuesto, si hay un código de inicialización en la
// función Constructor, el Object.create no puede reflejar esta.


// crear un nuevo objeto cuyo prototipo es un nuevo, objeto vacío
// y agregar una única propiedad 'p', con el valor 42
o = Object.create({}, { p: { value: 42 } })

// por defecto las propiedades NO SON editables, enumerables o configurables:
o.p = 24
o.p
// 42

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

delete o.p
// false

// para especificar una propiedad en ES3

o2 = Object.create({}, { p: {
      value: 42,
      writable: true,
      enumerable: true,
      configurable: true }
});

Objetos personalizados y nulos

A new object created from a completely custom object (especially one created from the null object, which is basically a custom object with NO members) can behave in unexpected ways. This is especially true when debugging, since common object-property converting/detecting utility functions may generate errors, or simply lose information (especially if using silent error-traps that ignore errors). For example, here are two objects:

oco = Object.create( {} );   // create a normal object
ocn = Object.create( null ); // create a "null" object

> console.log(oco) // {} -- Seems normal
> console.log(ocn) // {} -- Seems normal here too, so far

oco.p = 1; // create a simple property on normal obj
ocn.p = 0; // create a simple property on "null" obj

> console.log(oco) // {p: 1} -- Still seems normal
> console.log(ocn) // {p: 0} -- Still seems normal here too. BUT WAIT...


As shown above, all seems normal so far. However, when attempting to actually use these objects, their differences quickly become apparent:

> "oco is: " + oco // shows "ocn is: [object Object]"

> "ocn is: " + ocn // throws error: Cannot convert object to primitive value


Testing just a few of the many most basic built-in functions shows the magnitude of the problem more clearly:

> alert(oco) // shows [object Object]
> alert(ocn) // throws error: Cannot convert object to primitive value

> oco.toString() // shows [object Object]
> ocn.toString() // throws error: ocn.toString is not a function

> oco.valueOf() // shows {}
> ocn.valueOf() // throws error: ocn.valueOf is not a function

> oco.hasOwnProperty("p") // shows "true"
> ocn.hasOwnProperty("p") // throws error: ocn.hasOwnProperty is not a function

> oco.constructor // shows "Object() { [native code] }"
> ocn.constructor // shows "undefined"


As said, these differences can make debugging even simple-seeming problems quickly go astray. For example:

Una función simple de depuración:

// display top-level property name:value pairs of given object
function ShowProperties( b ){
  for( var i in b ){  console.log( i + ": " + b[i] + "\n" )  }
}


Not such simple results: (especially if silent error-trapping had hidden the error messages)

ob={}; ob.po=oco; ob.pn=ocn; // create a compound object using the test objects from above as property values

> ShowProperties( ob ) // display top-level properties
- po: [object Object]
- Error: Cannot convert object to primitive value

Note that only first property gets shown.


(But if same object is created simply in different order -- at least in some implementations...)

ob={}; ob.pn=ocn; ob.po=oco; // create same compound object again, but create same properties in different order

> ShowProperties( ob ) // display top-level properties
- Error: Cannot convert object to primitive value

Note that neither property gets shown.

Note that such a different order may arise statically via disparate fixed codings such as here, but also dynamically via whatever the order any such property-adding code-branches actually get executed at runtime as depends on inputs and/or random-variables. Then again, the actual iteration order is not guaranteed no matter what the order members are added.

Algunas NO-soluciones

A good solution for the missing object-methods is not immediately apparent.

Adding the missing object-method directly from the standard-object does NOT work:

ocn = Object.create( null ); // create "null" object (same as before)

ocn.toString = Object.toString; // since new object lacks method then try assigning it directly from standard-object

> ocn.toString // shows "toString() { [native code] }" -- missing method seems to be there now
> ocn.toString == Object.toString // shows "true" -- method seems to be same as the standard object-method

> ocn.toString() // error: Function.prototype.toString requires that 'this' be a Function


Adding the missing object-method directly to new object's "prototype" does not work either, since new object does not have a real prototype (which is really the cause of ALL these problems) and one cannot be directly added:

ocn = Object.create( null ); // create "null" object (same as before)

ocn.prototype.toString = Object.toString; // Error: Cannot set property 'toString' of undefined

ocn.prototype = {};                       // try to create a prototype
ocn.prototype.toString = Object.toString; // since new object lacks method then try assigning it from standard-object  

> ocn.toString() // error: ocn.toString is not a function


Adding the missing object-method by using the standard-object as new object's prototype does not work either:

ocn = Object.create( null );        // create "null" object (same as before) 
Object.setPrototypeOf(ocn, Object); // set new object's prototype to the standard-object

> ocn.toString() // error: Function.prototype.toString requires that 'this' be a Function

Algunas soluciones aceptables

Again, adding the missing object-method directly from the standard-object does NOT work. However, adding the generic method directly, DOES:

ocn = Object.create( null ); // create "null" object (same as before)

ocn.toString = toString; // since new object lacks method then assign it directly from generic version

> ocn.toString() // shows "[object Object]"
> "ocn is: " + ocn // shows "ocn is: [object Object]"


ob={}; ob.pn=ocn; ob.po=oco; // create a compound object (same as before)

> ShowProperties(ob) // display top-level properties
- po: [object Object]
- pn: [object Object]

However, setting the generic prototype as the new object's prototype works even better:

ocn = Object.create( null );                  // create "null" object (same as before)
Object.setPrototypeOf(ocn, Object.prototype); // set new object's prototype to the "generic" object (NOT standard-object)

(In addition to all the string-related functions shown above, this also adds:)

> ocn.valueOf() // shows {}
> ocn.hasOwnProperty("x") // shows "false"
> ocn.constructor // shows "Object() { [native code] }"

// ...and all the rest of the properties and methods of Object.prototype.

As shown, objects modified this way now look very much like ordinary objects.

Polyfill

Este polyfill cubre el caso de uso principal  el cual es la creación de un nuevo objeto para el prototipo que ha sido escogido pero no toma el segundo argumento en cuenta.

Note that while the setting of null as [[Prototype]] is supported in the real ES5 Object.create, this polyfill cannot support it due to a limitation inherent in versions of ECMAScript lower than 5.

 if (typeof Object.create !== "function") {
    Object.create = function (proto, propertiesObject) {
        if (typeof proto !== 'object' && typeof proto !== 'function') {
            throw new TypeError('Object prototype may only be an Object: ' + proto);
        } else if (proto === null) {
            throw new Error("This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument.");
        }

        if (typeof propertiesObject != 'undefined') {
            throw new Error("This browser's implementation of Object.create is a shim and doesn't support a second argument.");
        }

        function F() {}
        F.prototype = proto;

        return new F();
    };
}

Especificaciones

Especificación Estado Comentario
ECMAScript 5.1 (ECMA-262)
La definición de 'Object.create' en esta especificación.
Standard Definición inicial. Implementado en JavaScript 1.8.5
ECMAScript 2015 (6th Edition, ECMA-262)
La definición de 'Object.create' en esta especificación.
Standard  
ECMAScript Latest Draft (ECMA-262)
La definición de 'Object.create' en esta especificación.
Draft  

Compatibilidad con navegadores

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidEdge MobileFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
Soporte básicoChrome Soporte completo 5Edge Soporte completo SiFirefox Soporte completo 4IE Soporte completo 9Opera Soporte completo 11.6Safari Soporte completo 5WebView Android Soporte completo SiChrome Android Soporte completo SiEdge Mobile Soporte completo SiFirefox Android Soporte completo 4Opera Android Soporte completo 11.5Safari iOS Soporte completo SiSamsung Internet Android Soporte completo Sinodejs Soporte completo Si

Leyenda

Soporte completo  
Soporte completo

Ver también

Etiquetas y colaboradores del documento

Colaboradores en esta página: mdnwebdocs-bot, AlePerez92, jacoborus, teoli, Siro_Diaz, carlosmantilla
Última actualización por: mdnwebdocs-bot,