2011-01-31 17 views
5

Presume Ho un oggetto come questo:Come emulare un costruttore con ES5 Object.create e la sintassi letterale dell'oggetto?

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

Problema: Voglio inizializzare che sprite con lo src destra. Tuttavia, quando uso la seguente tecnica di creazione:

var f = Object.create(Foo); 

non ho un metodo di costruzione (funzione aka init) per impostare sprite.src = 'cool.png';

La mia domanda:

se sto usando l'oggetto tecnica letterale e Object.create(), quando posso effettivamente inizializzare alcuni dei miei stato interno (come l'esempio del new Image())

la mia soluzione:

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

Tuttavia, non so se questo è un grande schema. Mi piacerebbe fare questo il "JavaScript Way" se c'è un modo. :)

Grazie!

+1

Sembra si preferisce rendere il complesso codice di sfruttare la semplicità del sistema di oggetti. – ChaosPandion

risposta

-10

Per tagliare una lunga storia breve: Non provare. L'idea di base di Object.create è evitare le funzioni di costruzione. È meglio utilizzare questo modello di buon vecchio:

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

Quindi utilizzare new Foo invece di Object.create.

+0

fornire alcuni argomenti sul motivo per cui non dovrebbe provarlo per favore – a0viedo

+0

@ a0viedo Fondamentalmente perché aggiunge inutile confusione al codice. Ogni istanza di 'Foo' erediterebbe un metodo' create() 'che crea i fratelli. Perché qualcuno dovrebbe volerlo? – user123444555621

+0

Con questo costrutto, ogni istanza di Foo erediterà un metodo create() che crea i bambini: function create() {return Object.create (this); } –

0

vorrei semplicemente fare questo:

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

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

Va detto che questo richiede la buona vecchia parola 'new' piuttosto che un' Object.create', e non crea la catena di prototipi che l'OP vuole. – user123444555621

4

Come posso supporre da questo link si dovrebbe fare qualcosa di simile:

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

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

faccio qualcosa di molto simile a quello che hai scritto sopra, ma ho combinano con il modello di modulo:

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

Dall'esterno, questo espone Vehicle.create() e Vehicle.prototype. Poi se voglio fare un tipo derivato, posso fare questo:

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; 

})(); 

Questo modello mi permette di traggo tipi senza fare l'errore di Car.prototype = new Vehicle(), che è fallire se i miei costruttori prendono parametri.

Problemi correlati