2015-05-15 15 views
5

Sto rivedendo un codice JavaScript di un collega e ha scritto una funzione prototipo di Oggetto che ritengo non sia corretta riguardo i principi della programmazione orientata agli oggetti.È corretto invocare il costruttore di un oggetto JavaScript in una delle funzioni prototipo?

Game.prototype.reset = function() { 
    if (game.over) { 
     game.over = false; 
     game = new Game(players); 
    }  
} 

Un paio di righe di seguito, la variabile di gioco è stata dichiarata come variabile globale.

var game = new Game(players); 

Quindi, è corretto creare un nuovo oggetto di gioco da uno dei suoi costruttori? Il codice funziona perfettamente. Grazie!

risposta

4

Non deve fare riferimento alla variabile game all'interno del metodo prototipo, poiché game è il nome dell'istanza. Invece dovrebbe usare this per fare riferimento all'oggetto corrente.

All'interno del metodo reset non dovrebbe creato la nuova istanza gioco, ma veramente ripristinare i campi di gioco, qualcosa lungo sotto:

Game.prototype.reset = function() { 
    if (this.over) { 
     this.over = false; 
     this.initialize(this.players); 
    }  
} 

Game.prototype.initialize = function(players) { 
    this.players = players; 
    : 
} 
+0

Si presuppone che 'reset' debba reimpostare l'istanza su cui è chiamato. Potrebbe non essere il caso. – Oriol

+0

@Oriol Allora perché metterlo sul prototipo? Questa probabilmente non è una grande domanda per SO, ma questo solleverebbe sicuramente alcune domande in una revisione del codice. –

+0

@JamesMontagne Ad esempio, poiché il costruttore può essere definito all'interno di un ambito a cui non si ha accesso. Solo alcune istanze potrebbero essere state esportate all'esterno, quindi il metodo è stato inserito nel prototipo anziché ad es. il costruttore. Probabilmente non è il caso, ma è ancora possibile. – Oriol

0

Io non credo che ci sia qualcosa di sbagliato nell'uso Game costruttore all'interno prototipo Game.

Vedere l'esempio di seguito. ha un metodo chiamato cloneMe e crea un nuovo oggetto con valore di oggetti corrente.

function Game(name, team) { 
 
    this.playerName = name; 
 
    this.teamName = team 
 
    this.points = 0; 
 
} 
 

 
Game.prototype.goal = function() { 
 
    this.points += 1; 
 
} 
 

 
Game.prototype.cloneMe = function() { 
 
    return new Game(this.playerName, this.teamName); 
 
} 
 

 

 
var gameInst = new Game('jack', 'X-team'); 
 

 
gameInst.goal(); 
 
gameInst.points // will print 1 
 

 
gameInst.goal(); 
 
gameInst.points // will print 2 
 

 
// game varible got replaced with new variable 
 
var gameCloneInst = game.cloneMe(); 
 

 
gameCloneInst.goal(); 
 
gameCloneInst.points // will print 1

+0

Questo va bene, ma è diverso dal codice nella domanda. Il tuo metodo 'cloneMe' restituisce una nuova istanza di' Gioco'. Il codice nella domanda ha un metodo che modifica una variabile definita al di fuori del costruttore 'Game'. – leftclickben

1

Direi che questo è codice "errato" in quanto disobbedisce al principio di incapsulamento, perché un'istanza di una classe sta influenzando lo stato un'altra istanza di quella classe, senza che la seconda istanza venga passata come parametro (viene fuori dal nulla).

Direi anche che non è particolarmente utile definire un modo di parte del modulo tra un costruttore e un singleton.

Se game deve essere un singleton, definirlo come un singleton, collegarlo all'ambito globale (o meglio utilizzare un modulo loader) e utilizzarlo come un singleton. Dargli un metodo reset che utilizza this per riportare il proprio stato interno ai valori iniziali.

Se Game deve essere un costruttore, di cui possono esserci molte istanze, definirlo come costruttore e creare istanze quando necessario, quindi passare tali istanze come parametri dove necessario.

Personalmente userei un costruttore, e non avrei affatto un metodo reset. Quando il gioco viene ripristinato dall'utente, creo una nuova istanza di Game. Ma un singleton correttamente definito sarebbe migliore del codice che è nella domanda.

Problemi correlati