I am creating a game with many objects, these objects all have their own functions that get called. I have one object that does not do anything and is just for cloning, when this object is cloned everything but the functions get cloned. the x-y gets cloned as well as other this like weight and strength. but the functions don't get cloned. The method I use for cloning is this.
objects[1] = JSON.parse(JSON.stringify(objects[0]))
This is not the only clone method I have tried, but all of them gave me the same result. I expect this to clone the object from objects[0] to objects[1] with everything including functions. (they are in an array so I can execute their functions). But only everything but functions are cloned.
Here is an example I made in node.js. (I don't have the anything solid in code as I like to test if it will work before putting it all together).
var original = {};
original.a = true;
original.b = null;
original.c = 82;
original.d = "a string LOL";
original.e = function() {
console.log("everything does not work?");
}
original.f = [0, "a", true, false];
console.log(original)
console.log(JSON.stringify(original));
console.log(JSON.stringify(JSON.parse(JSON.stringify(original))));
I am creating a game with many objects, these objects all have their own functions that get called. I have one object that does not do anything and is just for cloning, when this object is cloned everything but the functions get cloned. the x-y gets cloned as well as other this like weight and strength. but the functions don't get cloned. The method I use for cloning is this.
objects[1] = JSON.parse(JSON.stringify(objects[0]))
This is not the only clone method I have tried, but all of them gave me the same result. I expect this to clone the object from objects[0] to objects[1] with everything including functions. (they are in an array so I can execute their functions). But only everything but functions are cloned.
Here is an example I made in node.js. (I don't have the anything solid in code as I like to test if it will work before putting it all together).
var original = {};
original.a = true;
original.b = null;
original.c = 82;
original.d = "a string LOL";
original.e = function() {
console.log("everything does not work?");
}
original.f = [0, "a", true, false];
console.log(original)
console.log(JSON.stringify(original));
console.log(JSON.stringify(JSON.parse(JSON.stringify(original))));
Share
Improve this question
asked Apr 3, 2021 at 23:41
Haydan FisherHaydan Fisher
832 silver badges5 bronze badges
6
- 3 You can't keep functions once converted to JSON, as JSON is a string. – evolutionxbox Commented Apr 3, 2021 at 23:42
- @evolutionxbox the string is not important, just that the objects don't get cloned, and I showed that what I tried did not work. – Haydan Fisher Commented Apr 3, 2021 at 23:45
- What do you mean the string is not important? It's the reason why using JSON does not work... – evolutionxbox Commented Apr 3, 2021 at 23:54
- What I mean by the string is not important is that I don't have to use JSON strings, If there was another way, I could do it. – Haydan Fisher Commented Apr 4, 2021 at 4:04
- ah I see. Hopefully the given answers will help you there – evolutionxbox Commented Apr 4, 2021 at 10:16
3 Answers
Reset to default 3It's not possible to stringify functions using JSON.stringify
. Only a subset of primitives are valid JSON. For pleteness, function source code can be retrieved with toString
and rebuilt with the Function
constructor, but that's messy and unnecessary.
You can use Object.assign
or spread syntax:
var original = {};
original.a = true;
original.b = null;
original.c = 82;
original.d = "a string LOL";
original.e = function() {
console.log("everything does not work?");
}
original.f = [0, "a", true, false];
var copy = Object.assign({}, original);
var spread = {...original};
copy.f = [42, 45];
spread.f = [1, 2];
copy.e();
console.log(original.f, copy.f, spread.f);
Note that this isn't a deep (recursive) copy, so if you have nested objects, you'll have a shared alias. See What is the most efficient way to deep clone an object in JavaScript? if you want to deep copy.
You also mention you "have one object that does not do anything and is just for cloning". It sounds like you want a class or constructor of some sort. Absent more information, I prefer a function that returns an object and acts as a closure on any hidden properties you might want (you could also use a traditional constructor with this
as described here):
const makeFoo = () => ({
a: true,
b: null,
c: 82,
d: "a string LOL",
e: function () {
console.log("everything does not work?");
},
f: [0, "a", true, false],
});
const foos = [...Array(3)].map(makeFoo);
foos[0].c = 42;
console.log(foos);
You can parameterize some or all of these attributes with optional default values:
const makeFoo = props => {
const defaults = {
a: true,
b: null,
c: 82,
d: "a string LOL",
e: function () {
console.log("everything does not work?");
},
f: [0, "a", true, false],
};
return {...defaults, ...props};
};
const foos = [...Array(3)].map(() => makeFoo({a: false, b: 5}));
foos[0].c = 42;
console.log(foos);
...but I'm speculating a lot on your use case.
The best option out there is the cloneDeep
method offered by lodash. This will clone all primitives and all nested objects, and ofc you won't loose functions declarations
You can use the same structured clone mechanism that the HTML standard includes for sending data between realms: structuredClone
const clone = structuredClone(original);