Many array prototype functions work in an immutable way like map and reduce
arr[3] = 'New content';
Updating an array element immutably arr = arr.map((element, index) => {
if (index === 3) return 'New content';
return element;
});
It's possible, sure, but it feels terrible. JavaScript objects want to be mutated - it's the most idiomatic way of interacting with them. Whether functional programming paradigm is good (I certainly feel it is) is beside the point - JS wasn't designed for it.When I think of immutable primitives, I think of Python's tuples, which will raise a big fat error when you try to mutate them, or even better, Swift's structs, which gives you a new copy with every mutation.
arr = arr.map((e,i) => i === 3 ? 'new content' : e)
That said, idiomatic or not, functional patterns in JS are a boon for debugging (especially with Redux devtools & time travel). To your example, even if mutability is more succinct, using map() lets me chain all sorts of methods together without storing intermediate values in vars.Between the spread operator (...), immutable array methods (slice, reduce, map, filter, and even sort if preceded by .slice()), immutability in native JS ain't half bad.
This can avoid boilerplate traditionally associated with immutable updates in JavaScript, because you just write
const copy = transform(original, stage => {
stage.someArray[index] = 42;
});
and it returns immutable copy of original object with appropriate mutations. (set arr 3 "New content")
(set-in
deeply-nested
[arbitraty path to the element]
"New content")
convenient updates of immutable datastructures are possible. arr = [
...arr.slice(0, 2),
'New Content',
...arr.slice(3)
]In the version you have 2 spread operators, an array construct and 3 hardcoded ints.
I might not use the correct academic terms, and I might not be yet fully accustomed to es2015, but this way of writing stuff always make me pause and double check the code.