📋

JavaScriptのオブジェクト操作で可変から不変にする一覧

2022/11/04に公開約1,900字

前提

JavaScriptではconstで配列を使用しても値が変わる。
MDNでは次のように書かれている。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/const

const 宣言は、値への読み取り専用の参照を作ります。これは、定数に保持されている値は不変ではなく、その変数の識別子が再代入できないということです。たとえば、定数の中身がオブジェクトの場合、オブジェクトの内容(プロパティなど)は変更可能です。

なのでオブジェクト(配列含む)は基本的にコピーしてから操作する
なお、プリミティブ型はもともとイミュータブルなので書き換えることはできない
forEach, map, filter, reduce ... は扱わない(These are 教養!)
ここでは可変な操作を不変で置き換える方法一覧を置いておく

Array

push()

const newArray = [...ary, elm1, elm2]

unshift()

const newArray = [elm1, elm2, ...ary]

pop()

const elm = ary[length-1]
const newArray = ary.slice(0, ary.length-1)

shift()

const elm = ary[0]
const newArray = ary.slice(1)

splice()

const newArray = [...ary.slice(0, 1), ...[elm1, elm2], ...ary.slice(2)]

sort()

const newArray = [...ary].sort()

reverse()

const newArray = [...ary].reverse()

Object

Object.preventExtensions(): 追加 ×
Object.seal(): 追加、削除 ×
Object.freeze(): 追加、削除、変更 ×

プロパティ追加 obj.newKey = newValue

const newObj = {...obj, newKey1: newValue1, newKey2: newValue2}

既存のプロパティ変更 obj.existKey = newValue

const newObj = {...obj, existKey1: newValue1, existKey2: newValue2 }

プロパティの削除 delete obj.existKey

const { existKey1, existKey2, ...newObj} = obj

ネストした構造の場合

個別にスプレッド構文{...obj}を使った後に個別に変更

const newObj = {
  ...obj,
  existKey1: [...obj.existKey1],
  existKey2: {...obj.existKey2}
}
// ↓元のobjは変わらない
newObj.existKey1.push('newValue') 
newObj.existKey2.childkey = 'newValue'

{...JSON.parse(JSON.stringify(ary))}をした後に個別に変更

const newObj = {
   ...JSON.parse(JSON.stringify(obj)),
}
// ↓元のobjは変わらない
newObj.existKey1.push('newValue') 
newObj.existKey2.childkey = 'newValue'

参考URL

https://morioh.com/p/1c11f60f6585
https://iwb.jp/javascript-const-array-variable-not-change/
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/const

Discussion

ログインするとコメントできます