2010-07-02 15 views
7

Ho una matrice di oggetto esistente definita con JSON. Gli oggetti sono ovviamente del tipo Object. Come faccio ad associarli a un tipo di oggetto personalizzato per fornire loro funzionalità specifiche?Modifica del tipo di un oggetto in JavaScript

+0

se questo oggetto ha attributi aggiuntivi/metodi, di cosa hai bisogno di più? potresti fornire qualche esempio? – mykhal

+0

.. Voglio dire, hai già definito tipi di oggetti personalizzati o vuoi sapere come farlo? – mykhal

risposta

11

Il modo in cui lavoreremo in tutti i browser è o aumentare ogni elemento dell'array con le proprietà ei metodi che si desidera, o passare l'oggetto a un costruttore e creare un nuovo oggetto basato sul vecchio oggetto del proprietà e metodi.

O se non si cura di IE:

var obj = { 
    name : "Jeremy" 
}; 

function CustomType() { 
    this.name = this.name || "someValue"; 
    this.greeting = "Hi"; 
} 

CustomType.prototype.sayHi = function() { 
    alert(this.greeting + ", " + this.name); 
}; 

obj.__proto__ = CustomType.prototype; 
obj.constructor.call(obj); 

obj.sayHi(); 
+1

Mi interessa di IE e sono andato con il tuo suggerimento, creando un metodo che modifica l'oggetto passato e lo restituisce al chiamante. Sono troppo abituato a usare "benedica" in Perl ed essere in grado di modificare oggetti secondo il mio capriccio. – Ray

4

Non credo che ci sia un modo per cambiare il tipo di un oggetto una volta creato. Fortunatamente, probabilmente non hai realmente bisogno di cambiare la classe, dei tuoi oggetti - probabilmente sarai soddisfatto di dare agli oggetti alcuni nuovi metodi e altre funzionalità. (L'unica vera differenza è cosa succederebbe se modificassi la classe, e la maggior parte delle persone non cambiasse le classi mentre il codice è in esecuzione.)

Farò un esempio per te. In primo luogo, creerò un semplice oggetto per rappresentare gli oggetti JSON che avete:

var myobj = new Object() 
myobj.name = "Fred" 

Poi mi creerà qualche classe che si vorrebbe essere in grado di assegnare a myobj:

function Speaker() { 
    this.speak = function() { 
     window.alert("Hello, " + this.name); 
    } 
} 

Questo nuova classe Speaker ha alcune funzionalità utili: si può utilizzare il metodo speak() per emettere informazioni utili:

var s = new Speaker() 
s.name = "Sally" 
s.speak() 

esecuzione che ha dato m e il messaggio "Ciao, Sally". Sfortunatamente, con questa funzionalità non vuoi un NUOVO oggetto (come s), vuoi l'oggetto esistente (myobj) per averlo. Ecco come farlo:

myobj.speak = s.speak 

Ora, quando eseguo questo:

myobj.speak() 

Vedo il messaggio "Ciao, Fred".

Per riassumere: creare un oggetto che faccia ciò che si desidera. Copia tutti i metodi (e le eventuali variabili helper) nel tuo nuovo oggetto. Tranne alcuni usi insoliti dell'ereditarietà, questo farà sì che il tuo nuovo oggetto si comporti come desiderato.

2

Se si desidera utilizzare un metodo specifico su di essi è possibile utilizzare apply/call.

Oppure è possibile copiare i metodi per l'oggetto personalizzato.

function Object1() { 
    this.aValue = "10"; 
} 

function CustomObject() { 
    this.customValue = "6"; 
} 

function convertToCustom(obj) { 
    var custom = new CustomObject(); 
    for(var key in obj) { 
    custom[key] = obj[key]; 
    } 
    return custom; 
} 

var obj = new Object1(); 
var custom = convertToCustom(obj); 

console.log(custom.customValue); // <- 6 
console.log(custom.aValue);  // <- 10 
0

Come complemento alla risposta di Jeremy, si potrebbe usare Object.create invece di giocare direttamente con proto. Avrai anche bisogno di una funzione "estendere".

Quindi, dato l'esempio di Jeremy, si potrebbe avere qualcosa di simile:

var obj = { 
name : "Jeremy" 
}; 


function CustomType() { 
} 

CustomType.prototype.init = function(){ 
    this.name = this.name || "someValue"; 
    this.greeting = "Hi"; 
    return this; //let's make it fluent 
} 

CustomType.prototype.sayHi = function() { 
    console.log(this.greeting + ", " + this.name); 
}; 

function extend(obj, props) { 
    for(prop in props) { 
     if(props.hasOwnProperty(prop)) { 
      obj[prop] = props[prop]; 
     } 
    } 
    return obj; //let's make it fluent 
} 

obj = extend(Object.create(CustomType.prototype), obj).init(); 

obj.sayHi(); 
1

Se non avete bisogno di costruttore, si può fare come:

Object.assign(new CustomType, {}); 
Problemi correlati