0

When declaring a new local variable inside a function and assigning it to a global variable that is equal to an array, what is better?

Option 1: Using the Spread Operator:

let globalArray = [1, 2, 4];

function add (arr, value) {

  let newArray = [...arr];

  newArray.push(value);
  return newArray;
  
}

console.log(add(globalArray, "red"));

Option 2: NOT using the Spread Operator:

let globalArray = [1, 2, 4];

function add (arr, value) {

  let newArray = arr;

  newArray.push(value);
  return newArray;
  
}

console.log(add(globalArray, "red"));

I can't see the difference in the output. Should the Spread Operator be used or not?

Egor Ulybin
  • 57
  • 1
  • 6
  • 1
    The second one will mutate the global array, thus producing an observable effect. Therefore, it's impure. FP strives for purity in order to reign in side effects – VLAZ Aug 25 '21 at 11:35
  • 1
    Side note: `...` isn't, and can't be, an operator. Operators can't do what `...` does. – T.J. Crowder Aug 25 '21 at 11:36
  • Possible duplicate of [Copy array by value](https://stackoverflow.com/questions/7486085/copy-array-by-value) – Cerbrus Aug 25 '21 at 11:40
  • 1
    There is no "better". Your 2 code snippets are _functionally different_. One mutates the global variable, the other doesn't. What you use depends on what you need. – Cerbrus Aug 25 '21 at 11:41

1 Answers1

2

There is no "better" without criteria, although we can probably infer some criteria here. :-)

Using push without making a copy (your "NOT" option) mutates the original array passed to your function (the global one), which is usually not done in functional programming. FP tends to embrace using immutable data structures and pure functions (loosely: functions without side effects).

If you don't want to mutate the global array, use spread or concat or similar. For instance, with spread syntax (no need for push after, we can include value in the array literal):

let newArray = [...arr, value];

let globalArray = [1, 2, 4];

function add (arr, value) {
    const newArray = [...arr, value];
    return newArray;
}

const updated = add(globalArray, "red");
console.log(updated);
console.log(updated === globalArray); // false
console.log(globalArray); // unchanged
.as-console-wrapper {
    max-height: 100% !important;
}

If you want to mutate the global array, use push on the array passed in:

let globalArray = [1, 2, 4];

function add (arr, value) {
    let newArray = arr;
    newArray.push(value);
    return newArray;
}

const updated = add(globalArray, "red");
console.log(updated);
console.log(updated === globalArray); // true!
console.log(globalArray); // changed!
.as-console-wrapper {
    max-height: 100% !important;
}

...but again, that's not typically done in FP. As I understand it (I'm not deep into FP), even if you wanted to update globalArray, you'd usually do it by reassigning it: globalArray = add(globalArray, "red").

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875