JavaScriptのsortは配列の破壊的変更なのでtoSortedを使うべき

sortは配列の破壊的変更

sortとはJavaScriptの配列の並び替えメソッドです。

sortが並び替えという意味なので、並び替えメソッドということを知らない人はほとんどいないですが、これが元の配列そのものが書き換わる破壊的メソッドということを知らずに使用している人は一定数います。

例えば、以下のようにsortで単純に並び替えて代入すると、元の配列も並び替えて変更してしまいます。

❌️ sort

JavaScript
const arr = [10, 2, 5]
const sorted = arr.sort((a, b) => a - b) 
console.log(sorted) // [2, 5, 10]
console.log(arr)    // [2, 5, 10] ← 元の配列も変更されている

※ 数値の昇順の場合は sort() ではなく sort((a, b) => a - b) を使用します。

上記のような仕様のため、sortを使用すると元の配列を変更してしまうので、これが原因でバグが発生してしまうことがあります。

toSortedで元の配列を変えずに並び替える

前述のsortだと元の配列も並び替えてしまう問題はtoSortedを使用することで解決できます。

「toSort」ではなく「toSorted」なので、使い慣れていない方は書き間違えないよう注意が必要です。

✅ toSorted

JavaScript
const arr = [10, 2, 5]
const sorted = arr.toSorted((a, b) => a - b) 
console.log(sorted) // [2, 5, 10]
console.log(arr)    // [10, 2, 5] ← 元の配列が変更されていない

ちなみに配列の破壊的変更を防ぐために、sliceメソッドを間に入れるケースがありますが、古い書き方であり、sliceを入れている意図が理解されないことがあるので、現在はなるべく使わないほうが良いです。

JavaScript
const arr = [10, 2, 5]
const sorted = arr.slice().sort((a, b) => a - b) 
console.log(sorted) // [2, 5, 10]
console.log(arr)    // [10, 2, 5] ← 元の配列が変更されていない

reverseもtoReversedで破壊を防げる

reverseも破壊的変更を行うメソッドですが、toReversedという元の配列を変えないメソッドが用意されているので、現在はこちらを使用するのが好ましいです。

❌️ reverse

JavaScript
const arr = [10, 2, 5]
const sorted = arr.reverse() 
console.log(sorted) // [5, 2, 10]
console.log(arr)    // [5, 2, 10] ← 元の配列も変更されている

✅️ toReversed

JavaScript
const arr = [10, 2, 5]
const sorted = arr.toReversed() 
console.log(sorted) // [5, 2, 10]
console.log(arr)    // [10, 2, 5] ← 元の配列が変更されていない

spliceもtoSplicedで破壊を防げる

spliceも破壊的変更を行うメソッドですが、toSplicedという元の配列を変えないメソッドが用意されているので、現在はこちらを使用するのが好ましいです。

spliceだと以下のようなコードで代入できない問題もあるので直感的にわかりづらく、使い方を間違えて代入できていないケースがあります。

❌️ splice

JavaScript
const months = ['Jan', 'Mar', 'Apr', 'May']
const months2 = months.splice(1, 0, 'Feb')
console.log(months) // ['Jan', 'Feb', 'Mar', 'Apr', 'May']
console.log(months2) // [] ← 代入されない

✅ toSpliced

JavaScript
const months = ['Jan', 'Mar', 'Apr', 'May']
const months2 = months.toSpliced(1, 0, 'Feb')
console.log(months) // ['Jan', 'Mar', 'Apr', 'May']
console.log(months2) // ['Jan', 'Feb', 'Mar', 'Apr', 'May']

まとめ

  • sort, reverse, splice メソッドは元の配列を変えてしまう
  • toSorted, toReversed, toSpliced メソッドは元の配列を変えない
  • 破壊的メソッドは元の配列を変更するためバグの原因になりやすい

toSorted, toReversed, toSpliced メソッドは現在はChrome, Edge, Safari, Firefox, Operaなどのほとんどのブラウザで使用可能です。

特に理由がなければ「sort, reverse, splice」ではなく「toSorted, toReversed, toSpliced」のメソッドを使用することをオススメします。