🧐

配列のconstって意味なくね?の違和感から始める配列の"非"破壊的操作の勉強【Javascript/Typescript】

に公開2

Typescript初心者の時にconstを使っていると、
値の変更ができないのが使いづらいと思っていたのですが、その一方で、

「配列やオブジェクトの場合はconstでも中身の値は変更できるんだ!ラッキー!」
と思ってコーディングしていました。しかしある時、

「あれ、配列の中身の値を変えれたらconst使ってる意味なくね?letで良くね?」

そんな違和感に気付いてしまったエンジニアの方々が、配列の破壊的操作と"非"破壊的操作について学ぶきっかけになればと思い、この記事を書きました

破壊的操作とは

ここまで読んでくれた方は気付いるかもしれませんが、配列の破壊的操作とは、

配列やオブジェクトの中身の値を変更する操作

のことを指します。例えば、

// 配列の場合
const arr = [1, 2, 3];
arr.push(4); // 破壊的操作
console.log(arr); // [1, 2, 3, 4]
// オブジェクトの場合
const obj = { a: 1, b: 2 };
obj.a = 3; // 破壊的操作
obj.c = 4; // 破壊的操作
console.log(obj); // { a: 3, b: 2, c: 4 }

どちらのコードも、配列 (arr) やオブジェクト (obj) の中身の値が、操作前と操作後で変わっていることがわかります

これをしてしまうと、コードを読んでる時に配列やオブジェクトの中身が追うのが難しくなったり、配列やオブジェクトに予期しない変更が入り、バグが埋め込まれてしまう原因となります

じゃあ、"非"破壊的操作とは?

配列の非破壊的操作とは、元の配列やオブジェクトの中身の値を変更せずに、変更後の値を新しい変数に代入することです
具体的なコードで説明すると、

// 配列の場合
const arr = [1, 2, 3];
const newArr = [...arr, 4]; // 非破壊的操作
console.log(arr); // [1, 2, 3]
console.log(newArr); // [1, 2, 3, 4]
// オブジェクトの場合
const obj = { a: 1, b: 2 };
const newObj = { ...obj, c: 3 }; // 非破壊的操作
console.log(obj); // { a: 1, b: 2 }
console.log(newObj); // { a: 1, b: 2, c: 3 }

このように、元の配列やオブジェクト (arrobj) の中身は変更されず、新しい配列 (newArr) やオブジェクト (newObj) が作成されていることがわかります

また、配列に付属する関数の中でいえば、返値を返す関数 (filter, map, reduce, etc...) は基本的に配列を非破壊的操作することが可能です(※例外あり)
これらの関数について、以下の記事に詳しくまとめられいますので、参考にしてみてください

https://qiita.com/honey32/items/d7ec396b0f62ff65c7e6
https://typescriptbook.jp/reference/values-types-variables/array/array-operations

まとめ

配列やオブジェクトのconstに意味がないと気付いてしまったみなさんは、基本的には"非"破壊的操作を使いましょう
map関数やreduce関数、スプレッド構文は、非破壊的操作を実現するための有益なツールにやっているので、ぜひ使いこなせるようになっていきましょう!
reduce関数やスプレッド構文については、以下の記事でも解説しているので、よかったら参考にしてみてください

https://zenn.dev/kanamo/articles/39e8da9c41025d
https://zenn.dev/kanamo/articles/f2601b9f14fa51

Discussion