破壊的・非破壊的とは
特にJavaScriptの場合、配列を操作するときにはもとの配列を直接操作してしまっていないか意識する必要がある。
JavaScriptのArrayオブジェクトに属するメソッドには「破壊的な」メソッドが存在しており、「破壊的な」メソッドはもとの配列を直接操作(破壊)してしまう。一方で「非破壊的な」メソッドとは、配列を直接操作するのではなく、もとの配列のコピーに対して操作を行ってその結果を返す。
破壊的なメソッド例
これらのメソッドはもとの配列を直接変化させるので注意しなくてはいけない。特に、ReactのstateやVueのdataプロパティ(配列)を破壊的メソッドを使用すると変更が検知できなくなり変更に伴う更新がされなくなってしまう。
- splice()
- copyWithin()
- fill()
- pop()
- push()
- shift()
- unshift()
- reverse()
- sort()
破壊的なメソッドを使わなくても配列の操作は以下のように問題なくできる。
非破壊的な配列操作の例
要素の追加
スプレッド演算子を使用する。
IE非対応のため、 IE対応が必要な案件でES6を使ってコーディングを行う際、スプレッド構文は使えないので注意。
const articles = [
{ id:1, title:"javascript 非破壊・破壊メソッド" },
{ id:2, title:"Docker・laravel・...で環境構築をする" },
{ id:3, title:"Eloquentのcreate・saveの使い分け...説明する" },
]
// -Apiを叩いてidが4の記事を追加-
const newArticle = {id:4, title:"hogehoge"}
// スプレッド構文でarticlesを展開し、newArticleを追加する
const newArticles = [ ...articles, newArticle ]
要素の削除
filter()を使用する
例)idが1のブログ記事を削除したいので、画面上の削除ボタンから削除用のApiを叩き、DBから削除後に削除したブログ記事のidと一致する記事をarticlesの配列から削除する
const articles = [
{ id:1, title:"javascript 非破壊・破壊メソッド" },
{ id:2, title:"Docker・laravel・...で環境構築をする" },
{ id:3, title:"Eloquentのcreate・saveの使い分け...説明する" },
]
-Apiを叩いてidが1の記事を削除-
// filterを使って、idが1と等しくないデータを返す
const newArticles = articles.filter(article => article.id !== 1)
// 処理後は以下のようになる
const newArticles = [
{ id:2, title:"Docker・laravel・...で環境構築をする" },
{ id:3, title:"Eloquentのcreate・saveの使い分け...説明する" }
]
要素の編集
map()を使用する※reduce()でも可
例)idが1のブログ記事を編集したいので、画面上の編集ボタンから編集用のApiを叩き、DBから更新後に編集したブログ記事のidと一致する記事を更新する
const articles = [
{ id:1, title:"javascript 非破壊・破壊メソッド" },
{ id:2, title:"Docker・laravel・...で環境構築をする" },
{ id:3, title:"Eloquentのcreate・saveの使い分け...説明する" },
]
// -Apiを叩いてidが1の記事を編集し、レスポンスとして受け取ったupdatedArticleのidと一致する場合はupdatedArticleを返す-
// mapを使って、idが1と等しいデータは更新したarticleを返す
const newArticles = articles.map((article) => article.id === updatedArticle.id ? updatedArticle : article)
// 処理後は以下のようになる
const newArticles = [
{ id:1, title:"updatedArticleContent" },
{ id:2, title:"Docker・laravel・...で環境構築をする" },
{ id:3, title:"Eloquentのcreate・saveの使い分け...説明する" }
]
破壊的なメソッドを使いたいとき
もとの配列を変えてしまわないように、スプレッド演算子でコピーを作ってから操作するとOK。
const articles = [
{ id:1, title:"javascript 非破壊・破壊メソッド" },
{ id:2, title:"Docker・laravel・...で環境構築をする" },
{ id:3, title:"Eloquentのcreate・saveの使い分け...説明する" },
]
const newArticles = [...articles].reverse();
console.log(newArticles);
まとめ
いかがでしたでしょうか。本記事では、javascriptの破壊的・非破壊的メソッドについて紹介しています。特に、ReactのstateやVueのdataプロパティ(配列)を破壊的メソッドを使用すると変更が検知できなくなり変更に伴う更新がされなくなってしまうため、理解しておく必要があります。