Puede modificar la estructura JSON para almacenar la información de tipo. Si tiene muchos objetos para serializar y deserializar de ida y vuelta, esto ahorraría tiempo escribiendo código personalizado para cada objeto.
También tenga en cuenta que esto modifica la estructura JSON y agrega una propiedad __type__
a cada objeto personalizado. Creo que este es un enfoque más limpio que mantener archivos de configuración separados. Así que sin más preámbulos, esta es la forma en que funciona básicamente:
var fruitBowl = {..};
fruitBowl[0].eat();
fruitBowl[1].seeds[0].plant();
llamada serializar en el objeto de conseguir una representación JSON
var json = fruitBowl.serialize();
deserializar llamada en la cadena JSON codificado para reconstruir los objetos
var resurrected = json.deserialize();
ahora se puede acceder a las propiedades y métodos de compra sobre los objetos:
resurrected[0].eat();
resurrected[1].seeds[0].plant();
Funciona para cualquier nivel de objetos profundamente anidados, aunque podría ser un poco problemático por el momento. También es probable que no sea un navegador cruzado (solo probado en Chrome). Como el deserializador no está familiarizado con la función de constructor de un objeto, básicamente crea cada objeto personalizado sin pasar ningún parámetro. Configuré una demostración en funcionamiento en jsfiddle al http://jsfiddle.net/kSATj/1/.
La función constructora tuvo que ser modificado para tener en cuenta los dos aspectos es objetos se podrían crear
- directamente en Javascript
- reconstruido a partir de JSON
Todos los constructores necesitarían para dar cabida a la creación desde ambos extremos, por lo que cada propiedad debe tener asignado un valor de retorno predeterminado en caso de que no se pase nada.
function SomeObject(a, b) {
this.a = a || false; // defaultValue can be anything
this.b = b || null; // defaultValue can be anything
}
// one type of initialization that you can use in your code
var o = new SomeObject("hello", "world");
// another type of initialization used by the deserializer
var o = new SomeObject();;
o.a = "hello";
o.b = "world";
Como referencia, el JSON modificado parece:
{"fruitbowl":
[
{
"__type__": "Fruit",
"name": "apple",
"color": "red",
"seeds": []
},
{
"__type__": "Fruit",
"name": "orange",
"color": "orange",
"seeds":
[
{
"__type__": "Seed",
"size": "small",
"density": "hard"
},
{
"__type__": "Seed",
"size": "small",
"density": "soft"
}
]
}
]
}
Esto es sólo una función de ayuda para identificar los tipos simples:
function isNative(object) {
if(object == null) {
return true;
}
var natives = [Boolean, Date, Number, String, Object, Function];
return natives.indexOf(object.constructor) !== -1;
}
serializa un objeto en JSON (con información de tipo preservado):
Object.prototype.serialize = function() {
var injectTypes = function(object) {
if(!isNative(object)) {
object.__type__ = object.constructor.name;
}
for(key in object) {
var property = object[key];
if(object.hasOwnProperty(key) && !isNative(property)) {
injectTypes(property);
}
}
};
var removeTypes = function(object) {
if(object.__type) {
delete object.__type__;
}
for(key in object) {
var property = object[key];
if(object.hasOwnProperty(key) && !isNative(property)) {
removeTypes(property);
}
}
}
injectTypes(this);
var json = JSON.stringify(this);
removeTypes(this);
return json;
};
Deserialize (con objetos personalizados reconstituidas)
String.prototype.deserialize = function() {
var rawObject = JSON.parse(this.toString());
var reconstruct = function(object) {
var reconstructed = {};
if(object.__type__) {
reconstructed = new window[object.__type__]();
delete object.__type__;
}
else if(isNative(object)) {
return object;
}
for(key in object) {
var property = object[key];
if(object.hasOwnProperty(key)) {
reconstructed[key] = reconstruct(property);
}
}
return reconstructed;
}
return reconstruct(rawObject);
};
Para crédito adicional: Podría necesitar identificar mi fruta y semillas con "instanceof" en algún momento. –