Reputation: 32354
I'm trying to make a "copy" function and add it to the object's prototype. I planned to recursively typecheck and assign properties to a new object and then return the object... But, there seems to be a problem, see this snippet of code:
Object.prototype.copy = function()
{
for (prop in this)
{
console.log(prop); //Logs copy (the function)!!!
}
}
x = {"a": 1};
y = x.copy();
As I've pointed out in the comment, I found this very weird behavior, but why is this happening? The copy function should be in Object.prototype
, not in the instanced object itself! How do I fix it? Can I just set this.copy = undefined
, and still rely on Object.prototype.copy
?
This is the full code sample, as requested:
Object.prototype.copy = function()
{
var object = this; //The object we are copying.
var newObject = {}; //The object we will return.
//Cycle through the properties of the object we are creating, copy them recursively.
for (prop in object)
{
if (!Object.prototype.hasOwnProperty.call(this, prop) || object[prop] == null)
{
continue;
}
if (prop == "copy")
{
console.log("Well, blah."); //This never prints!
}
if (typeof(object[prop]) == "object" && !(object[prop] instanceof Array)) //If the object's property is another object...
{
newObject[prop] = object[prop].copy(); //Set the copy of it to the new object as well.
console.log("1 --- " + prop); //This prints copy - two times! That defies logic!
}
else if (typeof(object[prop]) == "object") //If it's an array...
{
newObject[prop] = object[prop].slice(); //Do it in a nicer fashion.
console.log("2 --- " + prop);
}
else //You're safe to copy it.
{
newObject[prop] = object[prop];
console.log("3 --- " + prop + " --- " + object[prop]);
}
}
return newObject;
}
Upvotes: 1
Views: 121
Reputation: 413720
There's a method called "hasOwnProperty" that you can use:
if (this.hasOwnProperty(prop)) { ... }
If the function returns true
the it's a "direct" property on the object.
If you fear that the "hasOwnProperty" method may be borked, you can do this:
if (Object.prototype.hasOwnProperty.call(this, prop)) { ... }
instead.
Newer versions of JavaScript have fancier ways of examining and controlling objects.
edit — also your updated code involves a problem that'll bite due to the nested calls to "copy": you didn't declare "prop" with var
, so after the call to copy an object, the value of "prop" will have changed! (Every call to "copy" shares the same variable, in other words.)
Upvotes: 3