I have an object with several methods that looks like this:
export const myObject = {
method1: function (arr, value) {
this.method2(arr, value)
this.method3(arr).filter(item => item === 'something')
},
method2: function (arr, value) {
if (true) {
value = 'change this value'
if (true) {
value = 'then change this'
arr = [...arr.slice(0, -1)]
}
}
arr = [...arr, value]
return arr
},
method3: function (arr) {
switch(arr.at(-1)) {
case 1:
arr = [...arr, 2]
break
case 2:
arr = [...arr, 1]
break
default:
arr = [...arr]
}
return this
},
My problem is when I call method2 from method1, I receive the same reference and not the mutated array. If I put console logs in my code I can actually see the changes:
myObject = {
method1: function (value) {
console.log('here my value is 10')
this.method2(value)
console.log('here my value is 10 again')
},
method2: function (value) {
value = value + 10
console.log('here my value is 20')
return value
console.log('see second log in method 1')
},
I’ve already tryed changing variable names, and using different ways to insert the old values in the array but always have the same problem: the returned value is the original array.
My method2 it works because I’m using with several components in the app, the problem is when I call this method from a sibling method, regarding method3, I can place that function inside method1 because isn’nt needed in any other place, but method2 as I said is reused in other components.
What I’m doing wrong here? Please sorry if I’m not clear this is my first post in the community, you have the related code here and the working app here: React Calculator
>Solution :
Javascript parameters are always passed by value. You can change properties of the value you pass in, and those changes will be visible to the calling method. But if you change the parameter to point to a different reference, that change will not be visible to the calling method.
For example:
function A(arr) {
arr[0] = 42;
console.debug("Inside A", arr);
// Output: [42, 1, 2, 3]
}
function B(arr) {
arr = arr.slice(1);
console.debug("Inside B", arr);
// Output: [1, 2, 3]
}
let x = [0, 1, 2, 3];
console.debug("Initial", x);
// Output: [0, 1, 2, 3]
A(x);
console.debug("After A", x);
// Output: [42, 1, 2, 3]
B(x);
console.debug("After B", x);
// Output: [42, 1, 2, 3]
The changes made by A are visible outside of the function, because it simply changes a property on the object that was passed in.
The changes made by B are NOT visible outside of the function, because it reassigned the parameter to refer to a different object instance.
In your example, you can get the updated array by using the return value of method2:
method1: function (arr, value) {
arr = this.method2(arr, value);
this.method3(arr).filter(item => item === 'something')
}
However, you cannot get the updated array out of method3.