\$\begingroup\$
\$\endgroup\$
1
Is there a better way to do this?
function Person(name)
{
this._type='Person';
this.name=name;
this.hello = function(){
alert('Hello '+this.name);
};
}
function object_to_instance(key, value)
{
if (!value.hasOwnProperty('_type'))
return value;
var obj= eval('new '+value._type+'()');
for (var property in value)
obj[property]=value[property];
return obj;
}
var people = [new Person('Harry'), new Person('Sally')];
var people_json = JSON.stringify(people);
var new_people = JSON.parse(people_json, object_to_instance);
new_people[0].hello();
1 Answer 1
\$\begingroup\$
\$\endgroup\$
Instead of eval
, you could create a Person
constructor that accepts an object:
function Person(arg)
{
if (typeof arg === 'string')
{
var name = arg;
this._type='Person';
this.name=name;
}
else if (typeof arg === 'object')
{
var value = arg;
for (var prop in value)
{
if (value.hasOwnProperty(prop))
{
this[prop] = value[prop];
}
}
}
}
// Move Person.hello() into the prototype
Person.prototype.hello = function()
{
alert('Hello '+this.name);
};
Then use the _type
to choose a constructor based on a predefined set of classes, rather than a (potentially) unsafe eval
:
var classes =
{
Person: Person
/* other potential classes to deserialize from here as well */
};
function object_to_instance(key, value)
{
if (!value._type) return value;
return new classes[value._type](value);
}
var people = [new Person('Harry'), new Person('Sally')];
var people_json = JSON.stringify(people);
var new_people = JSON.parse(people_json, object_to_instance);
new_people[0].hello();
- Basic demo: http://jsfiddle.net/mattball/VfRJn
- Using multiple classes: http://jsfiddle.net/mattball/VfwRv
answered May 5, 2012 at 3:54
default
var obj = new window[value._type](value.name);
(I think you could at least; I don't use classes in js). \$\endgroup\$