Do we really need spread operator?

https://www.w3schools.com/code/tryit.asp?filename=FTJ56VZG7FKI

I’ve tried both let newArr = [...arr] and let newArr = arr and got same result.
So, Now my question is what’s the difference spread make?
Do we actually need it when we want to clone an array?

They are not the same.

copy = arr

In this case, copy is just an alias of arr. Change in copy or arr affects each other.

copy = [...arr]

In this case, change in copy won’t affect arr; copy is clone of arr.

You don’t need spread operator to copy array, but it’s the shortest way to do it.

The spread operator is very useful when passing React props. When you pass props explicitly from a parent component down to child components you could end up having several components passing the same props. If you go and change one prop in the parent component you would then have to go to each and every child components that calls those props and manually update them.

If you pass the props with the spread operator, whenever the parent component changes any of the props i.e. {…props} any changes made in the parent component to the props are automatically updated in the child components.

You have a choice of arr.slice() or [...arr] or something like

function clone(arr) {
  let output = [];
  for (let i = 0; i < arr.length; i++) {
    output.push(arr[i]);
  }
  return output;
}

Cloning an array by way of the spread operator is a consequence of how rest/spread works, it isn’t the reason for it existing. But when using [...arr], the intent is arguably clearer than arr.slice()

As @gunhoo93 says, newArr = arr isn’t cloning at all, newArr is just a reference to exactly the same array.

Apart from that it’s cloning so changing the clone will not change the initial array (note it’s only a shallow clone though!*), it’s really helpful for mixing two arrays. The syntax is also short and clear. When you’re doing this hundreds of times, it can really make the code cleaner.

let arr1 = ["a", "b", "c"]
let arr2 = ["1", "2", "3"]
let mix = [...arr1, ...arr2] //  ["a", "b", "c", "1" ,"2", "3"]

or even better with objects, because with objects, duplicate properties are not duplicated, the last duplicate is the value. So say you have some default settings:

let defaults = {
   setting1: false,
   setting2: false,
}

You can mix in the state the user changed:

let change = {
   setting1: true
}

let settings_state = {
   ...defaults,
   ...change // last duplicate property determines value
}
// will give you:
// settings_state = {
//    setting1: true,
//    setting2: false,
// }

This can all also be used to pass an arbitrary amount of values in function calls.

* Regarding the shallow cloning. Anytime you do value = somevariable and that variable is an object or an array you are just creating a reference. You are not copying the values. Same thing with spread (it only loops and assigns one level deep). When you spread an array of objects, it’s only a shallow copy. So if you spread [object, object2, object3] you’re only copying the array and the references to the objects, but not the objects themselves. Note, you can nest spreads, but it’s better to have a function for deep cloning.