2013-04-20 6 views
6

Sto tentando di aggiungere una funzione a un array di oggetti a cui ogni oggetto ha accesso, ma che non deve essere aggiunto a ciascun oggetto separatamente.javascript condivisione delle funzioni tra tutti gli oggetti in un array

Lasciatemi fare un breve esempio.

Diciamo che ho un array contenente oggetti simili, ciascuno avente una struttura x e una proprietà y:

var objects = [{x:1, y:2}, 
       {x:0, y:5}, 
       {x:3, y:14} 
       ]; 

Vorrei calcolare la somma dei x e y per qualsiasi oggetto.

Primo approccio:

Per calcolare la somma per un oggetto, si potrebbe passare questo oggetto a una funzione predefinita in questo modo:

function xySum1(o) {return o.x + o.y;} 

objects[0].x  //--> returns 1 
objects[0].y  //--> returns 2 
xySum1(objects[0]) //--> returns 3 

Questo è abbastanza brutto e insoddisfacente, l'accesso alle proprietà x e viene eseguito in modo diverso. Inoltre, il mio codice è in posizioni diverse e la funzione xySum1 non è facilmente riconoscibile come creata per agire sugli oggetti dell'array.

Secondo approccio:

Si potrebbe scorrere l'array e aggiungere la funzione come proprietà a ciascun oggetto:

for (var i=0; i < objects.length; i++) { 
    objects[i].xySum2 = function() {return this.x + this.y;}; 
} 

Ora, la somma viene ottenuto

objects[0].x  //--> returns 1 
objects[0].y  //--> returns 2 
objects[0].xySum2() //--> returns 3 

che è molto meglio.

Problemi

Ci sono, tuttavia, problemi con questo approccio. In primo luogo, quando aggiungo un nuovo elemento all'array

objects.push({x:5,y:21}); 

allora la somma non può essere calcolato prima che la funzione è stata aggiunta all'oggetto

objects[3].xySum2() //-->TypeError 

Un altro problema è che ho molti oggetti, e molte funzioni da aggiungere a loro. Sembra uno spreco di spazio di memoria buono per aggiungere ciascuna funzione a ciascun oggetto singolarmente.

C'è un modo per farlo in modo più efficiente?

+6

Che dire di 'objects.xySum (0)'? – Bergi

+0

forse definire un costruttore, quindi le funzioni saranno nel prototipo? – user2264587

+0

Puoi anche definire un metodo Object.prototype come questo: 'Object.prototype.xySum = function() {return typeof this.x! == 'undefined' && typeof this.y! == 'undefined'? this.x + this.y: undefined;} '. – dfsq

risposta

8

Definire una classe:

function MyObject(x, y) { 
    this.x = x; 
    this.y = y; 
} 
MyObject.prototype = { 
    xySum2: function() { 
     return this.x + this.y; 
    }, x: 0, y: 0 
}; 

allora si può fare:

var objects = [ 
    new MyObject(1, 2), 
    new MyObject(0, 5), 
    new MyObject(3, 14) 
]; 
objects[0].xySum2(); // 3 

objects.push(new MyObject(5, 21)); 
objects[3].xySum2(); // 26 

In alternativa, questo è ciò che Bergi probabilmente voleva dire nel suo commento:

objects.xySum = function(index) { 
    return this[index].x + this[index].y; 
}; 

Questo approccio è un po 'più "sporco", ma consuma meno memoria.

+1

Grazie MaxArt per la tua risposta. C'è un modo per farlo una volta che la matrice di oggetti è già stata creata? Chiedo come viene passato da un'altra parte del programma che è fuori dal mio controllo. – ElRudi

+0

@ElRudi In questo caso suggerisco di usare l'alternativa: definire la funzione della matrice 'objects' e il gioco è fatto. Ricordati di ridefinirlo in ogni copia o porzione che farai di 'opzioni'. Oppure puoi sempre creare il tuo array di 'MyObject's usando gli elementi di' objects', come in 'new MyObject (objects [i] .x, objects [i] .y)' – MaxArt

+0

Quindi le mie opzioni: (1) definire una classe, aggiungere la funzione desiderata al suo prototipo -e fare un ciclo attraverso tutti gli oggetti nell'array ottenuto per creare per ciascuna un'istanza della classe con le stesse proprietà, (2) aggiungere la funzione al prototipo di 'Object' invece, che può o non può essere una pratica di codifica terribile - con il vantaggio di meno righe di codice e meno looping attraverso le matrici, o (3) aggiungere la funzione al _array_ invece che ai singoli oggetti - con lo svantaggio che è usata sintatticamente diverso da altre proprietà e non viene copiato insieme ai dati dell'oggetto. È giusto? – ElRudi

Problemi correlati