2011-01-31 6 views
5

presume que tiene un objeto como éste:Cómo emular un constructor con ES5 Object.create y object literal sintaxis?

var Foo = { 
    x: 5, 
    sprite: new Image() 
} 

Problema: Quiero inicializar que el sprite con el src derecha. Sin embargo, cuando se utiliza la siguiente técnica de creación:

var f = Object.create(Foo); 

no tengo un método constructor (también conocido como la función init) para configurar sprite.src = 'cool.png';

Mi pregunta:

si estoy usando el objeto técnica literal, y Object.create(), cuando en realidad no lo inicializar un poco de mi estado interno (como el ejemplo de la new Image())

mi solución:

var Foo = { 
    create: function() { 
    var f = Object.create(Foo); 
    f.sprite.src = 'cool.png'; 
    return f; 
    } 
} 

Sin embargo, no sé si ese es un gran patrón. Me gustaría hacer esto como "JavaScript Way" si hay una forma. :)

Gracias!

+1

Parece que prefiere hacer su complejo código de tomar ventaja de la simplicidad del sistema de objetos. – ChaosPandion

Respuesta

-10

para cortar una larga historia corta: No trate. La idea básica de Object.create es evitar las funciones de constructor. Es mejor que el uso de este buen viejo patrón:

var Foo = function (url) { 
    //this.sprite.src = url; // This will overwrite the prototype's src 
    this.sprite = new Image(); 
    this.sprite.src = url; 
}; 
Foo.prototype = { 
    x: 5, 
    sprite: new Image() // do you really want this? 
}; 

A continuación, utilice new Foo en lugar de Object.create.

+0

proporciona algunos argumentos sobre por qué no debería intentarlo, por favor – a0viedo

+0

@ a0viedo Básicamente porque agrega confusión innecesaria a su código. Cada instancia de 'Foo' heredará un método' create() 'que crea hermanos. ¿Por qué alguien querría esto? – user123444555621

+0

Con esta construcción, cada instancia de Foo heredará un método create() que crea hijos: function create() {return Object.create (this); } –

0

yo simplemente hacer esto:

function Image(src) { 
    this.src = src; 
} 

function Foo() { 
    this.x = 5; 
    this.sprite = new Image('cool.png'); 
} 
+0

Debe mencionarse que esto requiere la palabra clave goode olde 'new' en lugar de' Object.create', y no crea la cadena prototipo que desea el OP. – user123444555621

4

Como puedo asumir de esta link que debe hacer algo como:

function ImgInstance(src){ 
    var img=new Image(); 
    img.src=src; 
    return img; 
} 

Object.create(Foo, {sprite: {value: ImgInstance("url")}}); 
6

que hacer algo muy similar a lo que ha escrito anteriormente, pero combinarlo con el patrón módulo:

var Vehicle = (function(){ 
     var exports = {}; 
     exports.prototype = {}; 
     exports.prototype.init = function() { 
       this.mph = 5; 
     }; 
     exports.prototype.go = function() { 
       console.log("Going " + this.mph.toString() + " mph."); 
     }; 

     exports.create = function() { 
       var ret = Object.create(exports.prototype); 
       ret.init(); 
       return ret; 
     }; 

     return exports; 
})(); 

Desde el exterior, esto expone Vehicle.create() y Vehicle.prototype. Entonces, si quiero hacer un tipo derivado, puedo hacer esto:

var Car = (function() { 
     var exports = {}; 
     exports.prototype = Object.create(Vehicle.prototype); 
     exports.prototype.init = function() { 
       Vehicle.prototype.init.apply(this, arguments); 
       this.wheels = 4; 
     }; 

     exports.create = function() { 
       var ret = Object.create(exports.prototype); 
       ret.init(); 
       return ret; 
     }; 

     return exports; 

})(); 

Este patrón me permite derivo tipos sin hacer el error de Car.prototype = new Vehicle(), que es fallan si mis constructores toman parámetros.

Cuestiones relacionadas