Object.setPrototypeOf()

El m茅todo Object.setPrototypeOf() establece el prototipo (p.e., la propiedad interna [[Prototype]]) de un objeto especificado a otro objeto o sino establece null.

Adverdencia: Cambiar la propiedad [[Prototype]] de un objeto, debido a la naturaleza de la optimizaci贸n del acceso a propiedades de los motores modernos de JavaScript, es una operaci贸n bastante lenta, en todo todo navegador y motor de JavaScript. Los efectos sobre el rendimiento al alterar la herencia son sutiles y vastos., y no est谩n limitados a simplemente el tiempo gastado en la sentencia obj.__proto___ = ...,  but may extend to any code that has access to any object whose [[Prototype]] has been altered. If you care about performance you should avoid setting the [[Prototype]] of an object. Instead, create a new object with the desired [[Prototype]] using Object.create().

Sintaxis

Object.setPrototypeOf(obj, prototype);

Par谩metros

obj
El objeto al que se ha de establecer el prototipo.
prototype
El nuevo prototipo del objeto, (un objeto o null).

Descripci贸n

Arroja una excepci贸n del tipo TypeError si el objeto cuyo [[Prototype]] se va a modificar no es extensible de acuerdo con Object.isExtensible(). No hace nada si el parametro prototype no es un objeto o null (p.e., n煤mero, cadena, booleano, o undefined). De cualquier otra forma, este m茅todo cambia la propiedad [[Prototype]] del obj al valor nuevo.

Object.setPrototypeOf() est谩 en el 煤ltimo borrador del estandar ECMAScript6. Es considerado generalmente la manera adecuada de establecer el prototipo de un objeto, contra la propiedad m谩s controversial Object.prototype.__proto__ (en-US).

Ejemplos

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

Polyfill

Utilizando la vieja propiedad Object.prototype.__proto__ (en-US), podemos definir facilmente Object.setPrototypeOf si a煤n no est谩 disponible:

// Solo funciona en Chrome y FirefoxOnly works in Chrome y FireFox, no funciona en IE:
Object.setPrototypeOf = Object.setPrototypeOf || function(obj, proto) {
  obj.__proto__ = proto;
  return obj;
}

Agregando cadenas de prototipo

Una combinaci贸n de Object.getPrototypeOf() y Object.prototype.__proto__ permite agregar una nueva cadena de prototipos al nuevo  prototipo del objeto.

/**
*** Object.appendChain(@object, @prototype)
*
* Agrega el primer prototipo no-nativo de una cadena a un nuevo prototipo.
* Retorna @object (si es Primitivo (Primitive value) ser谩 transoformado a Objeto).
*
*** 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")
*
*  Agrega el primer prototipo no-nativo de una cadena a la Function.prototype nativa del objeto, luego agrega una
* ueva Function(["@arg"(s)], "@function_body") a la cadena.
* Retorna la funci贸n.
*
**/

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;
}

Uso

Primer ejemplo: Agregar una cadena a un prototipo

function Mammal() {
  this.isMammal = 'yes';
}

function MammalSpecies(sMammalSpecies) {
  this.species = sMammalSpecies;
}

MammalSpecies.prototype = new Mammal();
MammalSpecies.prototype.constructor = MammalSpecies;

var oCat = new MammalSpecies('Felis');

console.log(oCat.isMammal); // 'yes'

function Animal() {
  this.breathing = 'yes';
}

Object.appendChain(oCat, new Animal());

console.log(oCat.breathing); // 'yes'

Segundo ejemplo: Transofrmando un valor Primitivo en una instancia de su constructor y agregar su cadena al prototipo

function Symbol() {
  this.isSymbol = 'yes';
}

var nPrime = 17;

console.log(typeof nPrime); // 'number'

var oPrime = Object.appendChain(nPrime, new Symbol());

console.log(oPrime); // '17'
console.log(oPrime.isSymbol); // 'yes'
console.log(typeof oPrime); // 'object'

Tercer ejemplo: Agregando una cadena a la Function.prototype de un objeto y agregando una nueva funci贸n a la cadena

function Person(sName) {
  this.identity = sName;
}

var george = Object.appendChain(new Person('George'),
                                'console.log("Hello guys!!");');

console.log(george.identity); // 'George'
george(); // 'Hello guys!!'

Especificaciones

Especificaci贸n Estado Comentario
ECMAScript 2015 (6th Edition, ECMA-262)
La definici贸n de 'Object.setProtoypeOf' en esta especificaci贸n.
Standard Initial definition.

Compatibilidad del navegador

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help! (en-US)
Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support 34 31 (31) 11 (Yes) Sin soporte
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support Sin soporte Sin soporte 31.0 (31) ? Sin soporte Sin soporte

Ver tambi茅n