Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > [JSON] Changing the class of an object after its construction

Reply
Thread Tools

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

 
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      11-20-2005
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
 
Reply With Quote
 
 
 
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      11-20-2005
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
 
Reply With Quote
 
 
 
 
Raphael Jolivet
Guest
Posts: n/a
 
      11-20-2005

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
 
Reply With Quote
 
VK
Guest
Posts: n/a
 
      11-20-2005
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);

 
Reply With Quote
 
VK
Guest
Posts: n/a
 
      11-20-2005

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.

 
Reply With Quote
 
John G Harris
Guest
Posts: n/a
 
      11-20-2005
In article <ux%ff.1569$>, Raphael Jolivet
<> 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
 
Reply With Quote
 
Raphael Jolivet
Guest
Posts: n/a
 
      11-20-2005
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

 
Reply With Quote
 
Martin Honnen
Guest
Posts: n/a
 
      11-20-2005


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/
 
Reply With Quote
 
Rob Williscroft
Guest
Posts: n/a
 
      11-20-2005
Raphael Jolivet wrote in news:ux%ff.1569$ 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/
 
Reply With Quote
 
Raphael Jolivet
Guest
Posts: n/a
 
      11-20-2005

> 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.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Its a bird, its a plane, its.. um, an Attribute based System? thunk Ruby 14 04-03-2010 10:08 AM
Its a bird, its a plane, its.. um, an Attribute based System? thunk Ruby 0 04-01-2010 10:25 PM
Its a bird, its a plane, no ummm, its a Ruide thunk Ruby 1 03-30-2010 11:10 AM
Newbie needing assistance on object construction, array of an object as function argument... cantide5ga C++ 7 10-23-2007 10:06 PM
Default construction versus construction with initial values Ook C++ 10 10-08-2005 09:00 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57