はじめに
大前提として、そもそもJSには「値渡し」「参照渡し」がない、というのはひとまず忘れる
→よくわからない人は、以下の記事が参考になるかも(本文もコメントも参考になる)
→JavaScriptに参照渡し/値渡しなど存在しない - Qiita
この記事では便宜上「値渡し」「参照渡し」という単語を使っているが、ご留意いただきたい
よくあるオブジェクトをコピーできない問題
問題点
そのままだと参照渡しになる
(→正確には、オブジェクトを渡すと呼び出し元のオブジェクトが変更される)
const sourceObj = {
name: "Taro",
age: 12,
}
const copyObj = sourceObj
copyObj.name = "Jiro"
console.log(sourceObj.name)
// => "Jiro", 元のオブジェクトの値も変わる
console.log(copyObj.name)
// => "Jiro"
解決策
よくあるオブジェクトを値渡しする方法
(→正確には、オブジェクトをコピーする方法)
const sourceObj = {
name: "Taro",
age: 12,
}
const copyObj = Object.assign({}, sourceObj)
copyObj.name = "Jiro"
console.log(sourceObj.name)
// => "Taro", 元のオブジェクトには影響なし
console.log(copyObj.name)
// => "Jiro"
Object.assign({}, sourceObj)
の部分は、
{...sourceObj}
でもOK
配列の中のオブジェクトをコピーできない問題
問題点
配列の中のオブジェクトという構造をObject.assign()
でコピーすると、浅いコピー(オブジェクトへの参照のみをコピーし、オブジェクトそのものはコピーしない)になる
※[...sourceObjs[0]]
でも変わらず
const sourceObjs = [
{
name: "Taro",
age: 12,
},
{
name: "Goro",
age: 30,
},
]
const copyObj = Object.assign({}, sourceObjs[0])
copyObj.name = "Jiro"
console.log(sourceObj.name)
// => "Jiro", 元のオブジェクトの値も変わる
console.log(copyObj.name)
// => "Jiro"
解決策
一度、JSONにパースしてから再度オブジェクトに戻す
const sourceObjs = [
{
name: "Taro",
age: 12,
},
{
name: "Goro",
age: 30,
},
]
const copyObj = JSON.parse(JSON.stringify(sourceObjs[0]))
copyObj.name = "Jiro"
console.log(sourceObj.name)
// => "Taro", 元のオブジェクトには影響なし
console.log(copyObj.name)
// => "Jiro"
さいごに
JSONにパースしてから戻す方法がスマートだが、他の方法もあると思う
気が向いたら追記する
念押しとして、JSには「値渡し」「参照渡し」という概念がそもそもないことに注意