I'm writing my clone function in javascript.
That function recursively clone object (avoiding circular reference) and seem work well, but if the object (at some level) has a built in object reference, when i try to access to some property of cloned object (that appear correct) i've a type error.
This is my simple example with datetime (i know there are more efficent way for clone datetime object, but that is not my concern, what i need to do is clone a generic built object, datetimes are only an example) that semplificate my real clone method to a method that only shallow copy function and array but deep copy object (except for internal array and function) and not avoid circular reference. This is only a dimostration of the error (the same error i obtain with the complete clone function).
CODE :
var date = new Date () ;
var dateProto = date.__proto__ ;
var cloned = {} ;
var clonedProto = {} ;
function clone ( obj )
{
if ( obj instanceof Array )
return [] ;
if ( obj instanceof Function )
return obj ;
if ( obj instanceof Object )
{
var result = {} ;
var elems = Object.getOwnPropertyNames(obj) ;
var len = elems.length ;
for ( var i = 0 ; i < len ; i++ )
{
var prop = elems[i] ;
var elem = obj[prop] ;
result [ prop ] = clone ( elem ) ;
}
return result ;
}
return obj ;
}
cloned = clone ( date ) ;
clonedProto = clone ( dateProto ) ;
cloned.__proto__ = clonedProto ;
alert ( cloned.getDay() );
But this cause this type error when try to access to getDay method : Uncaught TypeError: this is not a Date object.
But i still do not understand why, cloned appear like date object, i know that methods are shared, i'am expecting strange behaviour when invoked (method refer to the object called "date", so the object internal state is "date" not "cloned") but not an error.
So why this error?
Thanks for help and sorry for my bad english.
Edited
According with the new idea suggested (both form RobG and form article posted by jfriend00 in the comment) to me i rewrite the clone function i that way.
function clone ( obj )
{
if ( obj instanceof Array )
return [] ;
if ( obj instanceof Function )
return obj ;
if ( obj instanceof Object )
{
var result = new obj.constructor() ;
result.__proto__ = clone ( obj.__proto__ ) ;
var elems = Object.getOwnPropertyNames(obj) ;
var len = elems.length ;
for ( var i = 0 ; i < len ; i++ )
{
var prop = elems[i] ;
var elem = obj[prop] ;
result [ prop ] = clone ( elem ) ;
}
return result ;
}
return obj ;
}
Now seems to work how i expected, but i do not understand why this piece of code : var result = new obj.constructor() ; make the difference.
Thanks a lot for the help.