We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I have two sketches, and in sketch 1, I have an object that is storing all the relevant data in sketch 1. In sketch 2, I would like to make a copy of the object, and make minor modifications. However, making these minor modifications is also changing sketch 1's object. How can I get it to not do this?
Here's a minimal example:
Output I want: The circles in sketch 1 have the same height, while the circles in sketch 2 have different heights
Output I get: Circles in both sketch 1 and 2 have different heights.
var sketch = function(p) {
p.eyes = new Eyes();
p.setup = function() {
p.createCanvas(200,200);
p.background(255);
}
p.draw = function() {
p.ellipse(p.eyes.left[0], p.eyes.left[1], 10);
p.ellipse(p.eyes.right[0], p.eyes.right[1],10);
}
}
var sketch2 = function(p) {
p.newEyes = main.eyes;
p.newEyes.left = [10,10];
p.newEyes.right = [50,50];
p.setup = function() {
p.createCanvas(200,200);
p.background(255);
}
p.draw = function() {
p.ellipse(p.newEyes.left[0], p.newEyes.left[1], 10);
p.ellipse(p.newEyes.right[0], p.newEyes.right[1],10);
}
}
function Eyes() {
this.left = [10,50];
this.right = [50,50];
}
var main = new p5(sketch, 'canvasDiv');
var main2 = new p5(sketch2, 'canvasDiv');
Answers
p.newEyes = main.eyes;
?! Why don't you use thenew
operator there too?p.newEyes = new Eyes;
#-oAnd btW, although it works, we shouldn't prefix our own stuff w/ p5's parameter p. :-@
Reserve it for p5.js API properties only:
const newEyes = new Eyes;
L-)Another advise. Avoid plural names for classes.
Rather than calling your class there Eyes, rename it as EyePair for example. *-:)
1 more advise: JS got keyword
class
already: >-)https://developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
So your class EyePair can be implemented as below instead: :ar!
However, for instance mode, we need to move all classes to the top, b/c declaring keyword
class
doesn't hoist likefunction
does! :-SOh, I thought 'function ObjectName(arg1,...) { ... }' was the way to write a class constructor in javascript. I'll try to use your syntax lol, I always wondered why the javascript constructor looked weird. Also thanks for the style advice.
As for using 'new', I didn't use it because I wanted my second object to inherit some of the same variables from the first object. Maybe my problem would be clearer if I had something like:
and then constructed it in sketch1 using the syntax:
When I create the object in sketch2, I want it to take the numeric values of this.left and this.right from the first object, not create new this.left/this.right values based on my current mouse coordinates. And furthermore, after 'copying' the this.left/this.right values, I want to be able to modify them in the new object without affecting the old object.
Now we can test it w/ these lines below in any JS console:
However as you can see, the clone() method has completely failed! @-)
The cloned EyePair's arrays are still affecting the original EyePair! 3:-O
The reason why is b/c at
return new EyePair(this.left, this.right);
, the very same arrays are being passed to thenew
instance. It's still a shallow cloning instead of a deep 1.You know, variables store an object's 1st memory address (a.K.a. pointer or reference). :-B
So both instances got their properties pointing at the same memory addresses.
If we modify any of the arrays' index from either instance, the same will happen to the other! :-\"
In order to fix that, we've gotta clone the arrays themselves as well.
There are many ways to do that in JS. But I've selected 3 below:
...
: https://developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operatorNow let's do the test again, shall we? ;;)
Now it's working. Modifying any of the cloned EyePair's arrays won't affect the original 1s! <:-P