JSON and the __proto__ property

C

cbetz.sicom

I am trying to serialize/unserialize objects while preserving their
(proto)type. After a lot of looking I discovered that I can take a
generic object and modify its __proto__ property so that it becomes
the object I want.

However, what I am *really* looking for is a way to automatically
preserve the prototype when serializing an object--even when that
object contains other objects. Specifically I want to be able to take
some JSON representing an object and have it automatically converted
into a javascript object with the correct prototype, not just some
generic object.

Let me explain...

function Bar() {
this.hello = function() { alert("hello from a Bar");}
}

function Foo() {
this.stuff=new Array();
this.stuff.push(new Bar());
this.hello = function() { alert("hello from a Foo"); }
}

var f=new Foo();
var anonymous_foo=JSON.parse(JSON.stringify(f));

Problem:
anonymous_foo.hello() will be undefined unless I do
anonymous_foo.__proto__ = new Foo()

Bigger problem:
anonymous_foo.stuff[0].hello() will also be undefined unless I do
something similar. However, what I if I don't know that that that
stuff[0] is a Bar... what if it is a Baz or something else?

Is there any issue with modifying JSON.parse/stringify so that it can
work with __proto__?
 
D

Douglas Crockford

I am trying to serialize/unserialize objects while preserving their
(proto)type. After a lot of looking I discovered that I can take a
generic object and modify its __proto__ property so that it becomes
the object I want.

However, what I am *really* looking for is a way to automatically
preserve the prototype when serializing an object--even when that
object contains other objects. Specifically I want to be able to take
some JSON representing an object and have it automatically converted
into a javascript object with the correct prototype, not just some
generic object.

Do two things when you define your constructors: First, have the constructor
take a single parameter that is a descriptor object. This is a good practice
because users of your constructor are not forced to memorize the order of the
parameters. Second, add a type member that holds the name of the constructor.

function Sample(desc) {
this.type = 'Sample';
this.foo = desc.foo;
this.bar = desc.bar;
}

When you call JSON.parse, give it a reviver function that will pass the
descriptor objects to the constructors.

data = JSON.parse(text, function (key, value) {
var type, Constructor;
if (value && typeof value === 'object') {
type = value.type;
if (typeof type === 'string') {
Constructor = window[type];
if (typeof Constructor === 'function') {
return new Constructor(value);
}
}
}
return value;
});

Don't mess with the __proto__ property. It is not in the standard and is not
portable.

http://www.JSON.org/json2.js
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top