Ok so as an example you have a function like this
function fadeObject(colour, time)
{
this.time = time;
this.newMask = colour.red;
this.oldMask = CreateColor(0, 0, 0, 0);
this.flagged = true;
this.destroy = false;
this.fadeTime = time;
this.fadeCount = 1;
Abort(this.newMask)
this.fadeColourDifference = {};
this.fadeColourDifference.red = (this.newMask.red - this.oldMask.red) / this.fadeTime;
this.fadeColourDifference.blue = (this.newMask.blue - this.oldMask.blue) / this.fadeTime;
this.fadeColourDifference.green = (this.newMask.green - this.oldMask.green) / this.fadeTime;
this.fadeColourDifference.alpha = (this.newMask.alpha - this.oldMask.alpha) / this.fadeTime ;
}
The Abort returns "0" just as it should, yet :
this.fadeColourDifference.red = (this.newMask.red - this.oldMask.red) / this.fadeTime;
returns that this.newMask has no properties?
It definatly DOES have properties as if I Abort and check ANY of those properties they are there and the object itself returns as a color object???
Im trying to pass a color between a few functions including as a property in a object created within on of those functions so this is frustrating as I don't wanna use the global scope
(edit - code tags fixed ~neo)
Nevermind, its my cloning function elsewhere in the script. Its not copying the properties aparrently
Anyone got a clone function they would like to share (Deep cloning)
Here you go, took me about 2 minutes to write:
function clone(o)
{
if (typeof o === 'object' && o !== null) {
var dolly = {};
for (var p in o) {
dolly[p] = clone(o[p]);
}
} else {
dolly = o;
}
return dolly;
}
I love JavaScript. :)
You probably already know this, but that will die on cyclic references. Also it won't quite work correctly if you extend any native prototypes, or if you try to copy an object that that inherits from another object. Additionally, instanceof will not work on the cloned objects. I haven't tried, but it probably won't clone native Sphere objects properly, either (IIRC some of them have important non-enumerable properties).
You probably want something like this (http://oranlooney.com/deep-copy-javascript/) instead.
If you can be completely sure that you won't be dealing with cyclic objects and you're not cloning native objects and you're not extending native prototypes and you don't check that anything is an instanceof a constructor function, that one will work (and is nice and simple). I'd guess those assumptions are true about 90% of the time, so you should probably be OK (the only commonly cloned Sphere native is Color, which I'm pretty sure has all enumerable properties).
Or this, Alpha123, one can use json2 with cycles to eliminate cyclic structures:
/**
* Serialize(obj : object);
* - Use this to JSON an object; AND preserve the data type.
**/
function Serialize(obj)
{
function Make(obj) {
var o = Assert.isArray(obj) ? [] : { zztype: obj.constructor.name };
for (var i in obj) {
if (Assert.is(obj[i], "object")) o[i] = Make(obj[i]);
else o[i] = obj[i];
}
return o;
}
if(Assert.is(obj, "object"))
return JSON.stringify(Make(obj));
else
return JSON.stringify(obj);
}
/**
* Deserialize(s : string);
* - Use this to parse a JSON object; AND restore the methods.
**/
function Deserialize(s)
{
function Make(o) {
var obj = [];
if (!Assert.isArray(o)) {
if (o.zztype in this) obj = new global[o.zztype]();
else {
Debug.log("Can't deserialize type: {?}", o.zztype, LIB_ERROR);
return;
}
}
for (var i in o) {
if (Assert.is(o[i], "object")) obj[i] = Make(o[i]);
else obj[i] = o[i];
}
if (!Assert.isArray(obj)) delete obj.zztype;
return obj;
}
return Make(JSON.parse(s));
}
/**
* DeepClone(obj : object);
* - generates a full, deep, and accurate copy of the object.
**/
function DeepClone(obj) {
return Deserialize(Serialize(obj));
}
But it's not going to be lightning fast. And really, all you need is a clone for the job. If it's a simple thing that needs cloning say a
point = {x: 0, y: 0 }; then you don't need a huge, fancy copier. LordEnglish's solution is fine for bigger, nested objects, and mine if you want full instanceof support and method keeping.
It doesn't clone native Sphere objects though. I'll have to have it find and add their .clone() methods.
(edit - cleaned up tags ~neo)
That's great until you want to clone something that wasn't created from a constructor function but has methods, which is a rather common situation....
I haven't tried it, but won't that not copy
DeepClone({a: 1, b: function () { return 2; }});
correctly?
Really, just use a proper deep copy algorithm. The implementation I linked to earlier even allows registering custom copiers, so it would be really easy to extend it to copy built-in Sphere types.
Umm, you are right it'll lose that function. But, I mean there's only so far one will go for cloning. I'd still say to just use one that suits the need. My method just uses prototype-preserving JSON, the cloning is just an application of those two algorithms.
Well, this does the trick:
/**
* ShallowClone(obj : object);
* - generates a shallow copy of the object.
**/
function ShallowClone(obj) {
var o = new global[obj.constructor.name]();
Absorb(o, obj);
return o;
}
But no cyclic structures :/
Here's an adaption of my earlier function that handles circular refs:
function clone(o)
{
var clones = arguments.length >= 2 ? arguments[1] : [];
if (typeof o === 'object' && o !== null) {
for (var i = 0; i < clones.length; ++i) {
if (o === clones[i].original) {
return clones[i].dolly;
}
}
var dolly = {};
clones.push({ original: o, dolly: dolly });
for (var p in o) {
dolly[p] = clone(o[p], clones);
}
return dolly;
} else {
return o;
}
};
I'd wager that the vast majority of the time you're going to be cloning simple data objects. For that, the above is sufficient. I see a lot of talk about preserving the cloned object's prototype chain, but really, if you have a constructor-created object that you want to clone, that object should ideally implement its own clone method. If it doesn't, you shouldn't try to clone it yourself anyway because you can't be sure changing all its references (deep copy or not) isn't going to break something.
but really, if you have a constructor-created object that you want to clone, that object should ideally implement its own clone method.
+1 on that!
Deep copying is a solved problem guys. Either of your solutions are great for 90% of cases (the cyclic version... 90.5%), but real JavaScript deep copiers that work for 100% of cases exist. (Like I mentioned earlier, the one I linked to can even handle Sphere native objects.)
but really, if you have a constructor-created object that you want to clone, that object should ideally implement its own clone method.
I agree, actually. However, sometimes you do want to copy objects not created from constructors (object literals or
Object.create'd objects are pretty common).
...and nobody caught the joke embedded in my clone() function code... tsk tsk. :D
Original clone!
edit: I didn't find 'dolly' as funny as the oxymoron: original clone/copy.
Dolly! :P
(To be honest, I'd only skimmed over your function the first time.)