Comprender la diferencia entre Object.create() y new SomeFunction()

Resuelto Matt asked hace 13 años • 11 respuestas

Recientemente me topé con el Object.create()método en JavaScript y estoy tratando de deducir en qué se diferencia de crear una nueva instancia de un objeto con new SomeFunction()y cuándo querrías usar uno sobre el otro.

Considere el siguiente ejemplo:

var test = {
  val: 1,
  func: function() {
    return this.val;
  }
};
var testA = Object.create(test);

testA.val = 2;
console.log(test.func()); // 1
console.log(testA.func()); // 2

console.log('other test');
var otherTest = function() {
  this.val = 1;
  this.func = function() {
    return this.val;
  };
};

var otherTestA = new otherTest();
var otherTestB = new otherTest();
otherTestB.val = 2;
console.log(otherTestA.val); // 1 
console.log(otherTestB.val); // 2

console.log(otherTestA.func()); // 1
console.log(otherTestB.func()); // 2
Expandir fragmento

Observe que se observa el mismo comportamiento en ambos casos. Me parece que las principales diferencias entre estos dos escenarios son:

  • El objeto utilizado en Object.create()realidad forma el prototipo del nuevo objeto, mientras que en las new Function()propiedades/funciones declaradas no forman el prototipo.
  • No puede crear cierres con la Object.create()sintaxis como lo haría con la sintaxis funcional. Esto es lógico dado el alcance del tipo léxico (vs bloque) de JavaScript.

¿Son correctas las afirmaciones anteriores? ¿Y me falta algo? ¿Cuándo usarías uno sobre el otro?

EDITAR: enlace a la versión jsfiddle del ejemplo de código anterior: http://jsfiddle.net/rZfYL/

Matt avatar Nov 12 '10 23:11 Matt
Aceptado

En pocas palabras, new Xse trata Object.create(X.prototype)de ejecutar adicionalmente la constructorfunción. (Y dándole la constructoroportunidad al returnobjeto real de que debería ser el resultado de la expresión en lugar de this).

Eso es todo. :)

El resto de las respuestas son simplemente confusas, porque aparentemente nadie más lee la definición de nuevo tampoco. ;)

 avatar Jul 30 '2013 16:07

El objeto utilizado en Object.create en realidad forma el prototipo del nuevo objeto, mientras que en la nueva forma Function() las propiedades/funciones declaradas no forman el prototipo.

Sí, Object.createconstruye un objeto que hereda directamente del que se pasó como primer argumento.

Con las funciones constructoras, el objeto recién creado hereda del prototipo del constructor, por ejemplo:

var o = new SomeConstructor();

En el ejemplo anterior, ohereda directamente de SomeConstructor.prototype.

Aquí hay una diferencia: Object.createpuedes crear un objeto que no hereda de nada, Object.create(null);por otro lado, si configuras SomeConstructor.prototype = null;el objeto recién creado heredará de Object.prototype.

No puede crear cierres con la sintaxis Object.create como lo haría con la sintaxis funcional. Esto es lógico dado el alcance del tipo léxico (vs bloque) de JavaScript.

Bueno, puedes crear cierres, por ejemplo, usando el argumento de descriptores de propiedad:

var o = Object.create({inherited: 1}, {
  foo: {
    get: (function () { // a closure
      var closured = 'foo';
      return function () {
        return closured+'bar';
      };
    })()
  }
});

o.foo; // "foobar"

Tenga en cuenta que estoy hablando del Object.createmétodo ECMAScript 5.ª edición, no del calce de Crockford.

El método está comenzando a implementarse de forma nativa en los navegadores más recientes; consulte esta tabla de compatibilidad .

Christian C. Salvadó avatar Nov 12 '2010 16:11 Christian C. Salvadó

Estos son los pasos que ocurren internamente para ambas llamadas:
(Pista: la única diferencia está en el paso 3)


new Test():

  1. crear new Object()objeto
  2. ajustado obj.__proto__aTest.prototype
  3. return Test.call(obj) || obj; // normally obj is returned but constructors in JS can return a value

Object.create( Test.prototype )

  1. crear new Object()objeto
  2. ajustado obj.__proto__aTest.prototype
  3. return obj;

Básicamente, Object.createno ejecuta el constructor.

Ray Hulha avatar Jan 29 '2013 23:01 Ray Hulha