LoginSignup
3
2

More than 3 years have passed since last update.

【JS】配列の中のオブジェクトの値渡し(正確には値渡しではない)

Last updated at Posted at 2021-02-02

はじめに

大前提として、そもそも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には「値渡し」「参照渡し」という概念がそもそもないことに注意

参考

3
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2