javascriptには、破壊的メソッドと呼ばれるオブジェクトの内容を書き換えてしまうメソッドが存在する。

オブジェクトの内容が変わってしまうことで、意図しないバグを発生させる恐れがあることを、開発者は意識して実装する必要がある。

const array = ["a", "b", "c"];
const reverse = array.reverse();

console.log(array); // ["c", "b", "a"] オブジェクトの内容が書き換わる
console.log(reverse); // ["c", "b", "a"]

対策

事前の配列のコピー

巷でよく見かける実装だが、事前に用意した一時的な変数(tmp)にコピーする手法。

コード自体が冗長かつ、コピーした変数がスレッド内に永続的に残り続けることによってメモリ消費も増えパフォーマンス的にも良くない。

const array = ["a", "b", "c"];

const arrayTmp = array.concat(); // copy
const reverse = arrayTmp.reverse();

console.log(array); // ["a", "b", "c"]
console.log(arrayTmp); // ["c", "b", "a"]
console.log(reverse); // ["c", "b", "a"]

スプレッド構文を用いた配列のコピー

ES2015からは、スプレッド構文が使えるようになったため、次のようなコードに置き換えることができる。

[...array]と書くことで配列のコピーを生成することができる。

const array = ["a", "b", "c"];
const reverse = [...array].reverse();

console.log(array); // ["a", "b", "c"]
console.log(reverse); // ["c", "b", "a"]

ほとんどの場合、破壊的メソッドを使用するときに元のオブジェクトを変更したいケースは少ないと思うので、明示的にコピーすべきである。

スプレッド構文は簡潔に書けるので、破壊的メソッドを使うときには組み合わせて書く癖をつけると良いだろう。