By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,508 Members | 1,915 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,508 IT Pros & Developers. It's quick & easy.

[JSON] Changing the class of an object after its construction

P: n/a

Hello there,

I have a bunch of objects that I store in a text file (to store
preferences),
after having serialized them with JSON.

Let's say I have my object :

obj1 = {
a : 1
b : 2
}

Then, serialized in a string :
"{a : 1, b:2}";

To get the object back (when loading it from prefrences), i do almost :
obj1 = eval("[a:1,b:2");

Ok, my object is now back, but actually, the source object was
a 'myClass' object, with lot of cool methods in it.

What if I want my new object to have all these cool methods ?
I've tried
obj1.prototype = new myClass();
But it doesn't work.

If I do :
obj1.coolMethod = (new myClass()).coolMethod,
I can get 'coolMethod' working fine.
But I don't want to list all my methods.
This is not nice for maintenance and not nice at all.

Any Idea ?

Thanks in advance,
Raphael
Nov 23 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a
Raphael Jolivet wrote:

First of all, there are no classes in JavaScript < 2/JScript < 7/ECMAScript
< 4. Those are object-oriented programming languages using prototype-based
inheritance.
obj1 = {
a : 1
b : 2
}

Then, serialized in a string :
"{a : 1, b:2}";

To get the object back (when loading it from prefrences), i do almost :
obj1 = eval("[a:1,b:2"); ^^^^^^^^
This will yield a syntax error. Is that why you wrote "almost"?
Ok, my object is now back, but actually, the source object was
a 'myClass' object, with lot of cool methods in it.

What if I want my new object to have all these cool methods ?
You have to add `myClass' into the object's prototype chain.
Right now only `Object' is in its prototype chain as due to
the Object literal, Object() was the constructor implicitly
used.
I've tried
obj1.prototype = new myClass();
But it doesn't work.


"Does not work" is a useless error description. [psf 4.11]

In fact, it MUST NOT work. `obj1' does not refer to a constructor
(i.e. a Function object), so that does not have a `prototype' property.
You are creating one with no intrinsic functionality here.

To make the prototype chain work, you need another prototype.
I found two ways for this:

a)
obj1.__proto__ = new myClass(); // JavaScript only, preserves properties

b)
obj1 = new myClass(); // works everywhere but perhaps resets properties
myClass.call(obj1); // I am not sure about that
HTH

PointedEars
Nov 23 '05 #2

P: n/a
Thomas 'PointedEars' Lahn wrote:
In fact, it MUST NOT work. `obj1' does not refer to a constructor
(i.e. a Function object), so that does not have a `prototype' property.
You are creating one with no intrinsic functionality here.

To make the prototype chain work, you need another prototype.
I found two ways for this:

a)
obj1.__proto__ = new myClass(); // JavaScript only, preserves properties


or

obj1.__proto__ = myClass.prototype;
PointedEars
Nov 23 '05 #3

P: n/a
VK
Raphael Jolivet wrote:
Ok, my object is now back, but actually, the source object was
a 'myClass' object, with lot of cool methods in it.


It would help to have more clear picture how of relations between obj1
and myClass before serialization.
JASON's marshalling includes native class methods as well as native
properties - I guess by its description as I did not use it yet too
much.
<http://www.crockford.com/JSON/js.html>

By some problem specifics I can guess that obj1 extends myClass and
inherits "a lot of cool" *static* methods from myClass. Usually
static methods of class-constructor are transient (not serializable)
because it's the opposite way is the best to crash your system on
de-serialization. Just think of objects coming back to you later and
each overriding the static method with its own "timestamped state" of
this method!

This is why right after the de-serialization obj1 is not yet really an
instance of myClass. It's so-called "skeleton": it has everything that
was his own, but it doesn't have yet inherited static members. The
simpliest way to put the flash back on it would be to pass it through
the myClass constructor once over again:

deserialize(obj1);
myClass.apply(obj1);

Nov 23 '05 #4

P: n/a
VK

VK wrote:
Raphael Jolivet wrote:
... obj1.prototype ....


My previous post also explain why you should not touch prototype of
neither obj1 nor myClass as it adds / casts *static* members so it
makes the picture more and more chaotoc on each de-serialization.

Nov 23 '05 #5

P: n/a
Thanks
"obj1.__proto__ = new myClass()" works well.

I though that "prototype" was a generic property to
manipulate the prototypes of objects, but you're right
It's only for constructors.

__proto___ was what I looked for.
Thanks
Thomas 'PointedEars' Lahn wrote:

In fact, it MUST NOT work. `obj1' does not refer to a constructor
(i.e. a Function object), so that does not have a `prototype' property.
You are creating one with no intrinsic functionality here.

To make the prototype chain work, you need another prototype.
I found two ways for this:

a)
obj1.__proto__ = new myClass(); // JavaScript only, preserves properties

or

obj1.__proto__ = myClass.prototype;
PointedEars

Nov 23 '05 #6

P: n/a
In article <ux****************@nntpserver.swip.net>, Raphael Jolivet
<ra***************************@laposte.net> writes

Hello there,

I have a bunch of objects that I store in a text file (to store
preferences),
after having serialized them with JSON.

Let's say I have my object :

obj1 = {
a : 1
b : 2
}

Then, serialized in a string :
"{a : 1, b:2}";

To get the object back (when loading it from prefrences), i do almost :
obj1 = eval("[a:1,b:2");

Ok, my object is now back, but actually, the source object was
a 'myClass' object, with lot of cool methods in it.

<snip>

Why not have two constructor functions with their prototype properties
the same.

When you make an object the first time you do
new Thing( <params> );
When you deserialise it you do
new InThing( <string> );

If Thing and InThing do what's needed you won't be able to tell the
difference between the two objects.

John
--
John Harris
Nov 23 '05 #7

P: n/a


Raphael Jolivet wrote:

"obj1.__proto__ = new myClass()" works well. __proto___ was what I looked for.


But be aware that only the Spidermonkey engine used in Mozilla and
Netscape browsers exposes that __proto__ property, other engines
implementing ECMAScript as the MS JScript engine or the engine used in
Opera do not expose that so using it in script on the web is not cross
browser.
--

Martin Honnen
http://JavaScript.FAQTs.com/
Nov 23 '05 #8

P: n/a
Raphael Jolivet wrote in news:ux****************@nntpserver.swip.net in
comp.lang.javascript:
What if I want my new object to have all these cool methods ?
I've tried
obj1.prototype = new myClass();
But it doesn't work.


<script type="text/javascript">
/** Copy an object to a new func()
*/
function copy_json( func, src )
{
var f = function() {}
f.prototype = func.prototype;
var dest = new f();
for ( var i in src ) dest[i] = src[i];
return dest;
}

/** Sample data
*/
var ob =
{
a : 1, b : 2, c : 3
};

/** Sample type with a prototype method
*/
function MyObject()
{
this.a = this.b = this.c = -1;
return this;
}
MyObject.prototype.upper = function()
{
return "{A:" + this.a + ",B:" + this.b + ",C:" + this.c + "}";
}

/** Does it work
*/
function test()
{
var copy = copy_json( MyObject, ob );

alert( copy.upper() + "\n" + (new MyObject()).upper() );
}
</script>

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Nov 23 '05 #9

P: n/a
But be aware that only the Spidermonkey engine used in Mozilla and
Netscape browsers exposes that __proto__ property, other engines
implementing ECMAScript as the MS JScript engine or the engine used in
Opera do not expose that so using it in script on the web is not cross
browser.


Ok, thanks for the hint.
But my intend is to develop some XUL stuff now. Only Moz/FF/ for now.
AJAX and cross-browser's stuff are way to tricky yet.

Nov 23 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.