I understand that JavaScript objects, including arrays, are automatically passed by reference, so I have something like this:
class Thing {
constructor( ) {
this.letters = [ "A", "B" ];
this.numbers = [ 1, 2, 3 ];
this.change( this.letters, this.numbers );
}
change( _letters, _numbers ) {
let l = _letters;
let n = _numbers;
l = [ ];
n = 6;
}
}
var t = new Thing( );
console.log( t );
The log request shows that there has been no change to the properties of Thing. And yet, under different conditions that I can not recognise, I have accidentally modified passed parameters inside a function, and have had to use something like n = Array.from( _numbers )
to avoid modifying the source property. Would someone be able to explain what is happening, and why?
I would like to pass object properties by reference such that I can modify more than one related property in a single function call, and thereby reserve the return value for debugging purposes.
Thank you.
The issue is the scoping. When you declared with let
, the declaration is scoped to the function change
and you are also reassigning the block-scoped variables here:
l = [ ];
n = 6;
If you want to change the class properties, you can do:
change(_letters, _numbers) {
this.letters = _letters; // `this` scoped to class
this.numbers = _numbers; // `this` scoped to class
}
See the example:
// simple demo start
let numbers = [1, 2, 3];
let n = numbers;
n.push(4)
console.info(n, typeof n);
n = 6; // reassign n
console.info(n, typeof n, numbers);
// simple demo end
// refactored class
class Thing {
constructor() {
this.letters = ["A", "B"];
this.numbers = [1, 2, 3];
this.change(this.letters, this.numbers);
}
change(_letters, _numbers) {
let l = _letters; // `let` is scoped to `change()`
let n = _numbers; // `let` is scoped to `change()`
l = []; // only changes scoped l
n = 6; // only changes scoped n
}
changeFix(_letters, _numbers) {
this.letters = _letters; // `this` scoped to class
this.numbers = _numbers; // `this` scoped to class
}
}
var t = new Thing();
console.log(t);
t.change(['C'], [4]);
console.info(t);
t.changeFix(['C'], [4]);
console.info(t);