Code Fix

上級

sort()やreverse()は新しい配列を返さず元の配列を書き換える

Array.prototype.sortやreverseは呼び出した配列自体を並べ替える破壊的(ミューテーティング)メソッドです。戻り値だけを見て「新しい配列が作られた」と考えると、元のデータまで書き換わっていることに気づけません。

なぜエラーが出ないのか

出力: 1
(エラーなし)
JavaScriptは何も報告しません。文法として正しいためです
出力: 1
実際の挙動 — 期待した結果と食い違っている箇所
見つけ方
エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます

このエラーが出る典型パターン

パターン1

 1  function displaySorted(scores) {
 2    return scores      .sort((a, b) => a - b);
                   ^
 3  }
 4  const original = [3, 1, 2];
 5  const sorted = displaySorted(original);
 6  console.log(original[0]);
出力: 1期待: 3 (エラーにはなりません)

sort()は呼び出した配列自体を並べ替える破壊的メソッドです。scoresをそのまま渡すと呼び出し元のoriginalまで並び変わってしまいます。

直し方: scores[...scores] にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  function topScore(scores) {
 2    return scores            .sort((a, b) => b - a)[0];
                      ^
 3  }
 4  const original = [10, 30, 20];
 5  topScore(original);
 6  console.log(original[0]);
出力: 30期待: 10 (エラーにはなりません)

sort()がscores(=original)を直接書き換えるため、関数を呼んだだけでoriginalの並び順まで変わってしまいます。

直し方: scores[...scores] にします。

この問題を解いてみる →

パターン3

 1  function displayReversed(items) {
 2    return items            .reverse();
                     ^
 3  }
 4  const original = ["a", "b", "c"];
 5  displayReversed(original);
 6  console.log(original[0]);
出力: c期待: a (エラーにはなりません)

reverse()もsort()と同じく破壊的メソッドです。itemsをそのまま渡すとoriginalの順序まで反転してしまいます。

直し方: items[...items] にします。

この問題を解いてみる →

よくある誤解

「関数に渡した配列は関数の外では変わらないはず」という思い込みは、破壊的メソッドを使う関数には当てはまりません。元のデータを保ちたい場合は、スプレッド構文などで複製してから並べ替える必要があります。

まとめ

sort()やreverse()は新しい配列を返さず元の配列を書き換えるは上級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)