🐡

JavaScriptの破壊的メソッドについて

2020/10/06に公開1

今回は、前の記事でも何度か取り上げたJavaScriptの破壊的メソッドについて取り上げたいと思います。

破壊的メソッドとは

まず破壊的メソッドとは、対象となる元の配列の値を変えてしまうメソッドの事です。

例えば、破壊的メソッドには以下のようなメソッドが当てはまります。

•sort()
•splice()
•push()
•shift()
•unshift()
•reverse() など

そして僕が実際に破壊的メソッドで頭を悩ませた例がこちらです。

numbers関数の引数に数値の入った配列を渡します。

console.log(numbers([1,4,3,9]))

以下、numbersの関数です。

const numbers = (arr) => {
  const downToUp = arr.sort((a,b) => (a < b ? -1 : 1 ));
  const upToDown = arr.sort((a,b) => (a < b ? 1 : -1));
  return [...downToUp, ...upToDown]
} 

ここで僕は、引数で渡した配列内の数値を.sort()メソッドを2度使って、昇順と降順の配列を2つ生成した後に1つの配列に結合するつもりでした。つまり返り値が

[1,3,4,9,9,4,3,1]

となって欲しかったのですが、実際の返り値は、

[ 9, 4, 3, 1, 9, 4, 3, 1]

となりました。ここが破壊的メソッドの注意するポイントです。
1回目の.sort()メソッドを使った時点で、元の配列である引数arrの配列の順番は昇順になり、その後の2回目の.sort()メソッドを使用した時点で元の配列である引数arrの配列の順番は降順になり、const downToUpも昇順だったはずが、降順になってしまいました。
この場合に元の配列の複製を作る事が必要になります。

const numbers = (arr) => {
  const copy = [...arr]
  const downToUp = arr.sort((a,b) => (a < b ? -1 : 1 ));
  const upToDown = copy.sort((a,b) => (a < b ? 1 : -1));
  return [...downToUp, ...upToDown]
} 

console.log(numbers([1,4,3,9])) //[1, 3, 4, 9, 9, 4, 3, 1]

スプレッド構文を使って配列の複製を生成する事で問題が解決しました。この場合では、問題が解決しましたが、破壊的メソッドで元の配列を変更してしまうのは、危険かなと感じていて、常に破壊的メソッドを使用する際は複製の配列を生成するようにした方が良いかなと思いました。
ぜひご意見があれば、お聞きしたいです。

Discussion

kanoyakanoya

対象となる元の配列の値を変えてしまうメソッドの事です。

"変えてしまう" と表現するといかにも悪であるかのようですが、"変えることができる" ことでパフォーマンスが良くなったり簡潔に処理できたりするケースも多々あります。
要は、破壊的/非破壊的それぞれのメリット/デメリットをきちんと理解して使い分けることが重要です。