Essentially, I want to be able to access an object's property by reference. Take a look at the code below;
class Point{
x:number;
y:number;
constructor(x,y)
{
this.x=x;
this.y=y;
}
}
const a = { first: new Point(8,9), second: new Point(10,12) };
let someBool = true;
function modifyProperty(a) {
let c = someBool? a.first: a.second;
let newPoint = new Point(0,0);
c = newPoint; // Doesn't work
someBool = !someBool;
}
modifyProperty(a);
console.log(a.first);
In this example, whenever I call modifyProperty() I want to alternate between changing one of the two properties in 'a'.
However, when I assign 'c' to either 'a.first' or 'a.second', it only passes by value. The only way I could think to fix this is by making the property itself an object, like this:
const a = { first: {value: new Point(8,9)}, second: {value: new Point(10,12)} };
And then I would just call c.value = newPoint
instead. This would work, but it's not a good solution, since you'd have to do this for every property in an object.
Is there no way better way to get these properties by reference? I know JS only supports pass-by-reference for objects and arrays, but what about instances of classes?
I know when Babel converts a class to normal Javascript they're treated like functions, but a function is not a primitive type - it's an object that is callable, so doesn't this work, and what would be a solution?
However, when I assign 'c' to either 'a.first' or 'a.second', it only passes by value
Yes, assignment always changes the value of the thing on the left side of =
,
there is no way to change it in Javascript or TypeScript.
One workaround is to use property name together with the object to which the property belongs, instead of reference:
type Pair<T> = { first: T, second: T }
function modifyProperty(a: Pair<Point>) {
let c: keyof Pair<Point> = someBool? 'first' : 'second';
// keyof Pair<Point> type annotation means
// that only property names of Pair could be assigned to c
let newPoint = new Point(0,0);
a[c] = newPoint;
someBool = !someBool;
}