LoginSignup
0
0

javaScriptのコピーについて

Posted at

javaScriptのコピーについて、少しつまづいた所があったから、備忘録として記録する。
意外と今までなんとなくで対応していたなと思ったので、今回を機に色々調べてみた。

javaScriptの型について

javaScriptは動的型付け言語ですが、データに対してちゃんと型はある。
分類としては、プリミティブ型・オブジェクト型に分けることができる。

以下、例を書いておく。

プリミティブ型

  • String
  • Number
  • BigInt
  • Boolean
  • Undefine
  • Symbol
  • Null

オプジェクト型

  • Object
  • Array
  • function
  • Date
    など

プリミティブ型以外は全てオブジェクト型となるため、様々な例が考えられる。

プリミティブ型とオブジェクト型の違い

プリミティブ型とオブジェクト型の違いとして、値の格納方法がある。
プリミティブ型は、変数に値を直接保存する方法に対して、オブジェクト型は、変数にオブジェクトへの参照を保存している。

つまり、オブジェクト型は、変数にオブジェクトへの参照(値が保存されているメモリのポインタ)が格納されているため、コピーした際他の変数にも影響してしまう。

プリミティブ型

index.js
let person = 'name'
let new_person = person
new_person = 'new_name';

console.log(person, new_person)

//出力値
name new_name

値が直接コピーされるため、新たなメモリに保存し、変数同士が独立している。

オブジェクト型

index.js
let person = {name: 'name', age: 3};
let new_person = person
new_person.name = 'new_name';

console.log(person, new_person)

//出力値
{ name: 'new_name', age: 3 } { name: 'new_name', age: 3 }

参照先がコピーされているため、元の変数にも影響が出ていることがわかる。

シャローコピーとディープコピー

object型には二つのコピー方法がある。
まずはシャローコピーについて。

シャローコピー

シャローコピーとは、コピー元のオブジェクトと同じ参照をコピーするため、参照場所のデータを共有することになる。
そのため、コピーした値を変更するとコピー元にも影響が出る可能性がある。

let person = [
    1, 
    {name: 'name2', age: 4}, 
    {name: 'name3', age: 5}
];

let new_person =[...person]
//参照先のデータを変更
new_person[1].name = 'new_name'
console.log(person, new_person)

//出力値
[ 1, { name: 'new_name', age: 4 }, { name: 'name3', age: 5 } ]
[ 1, { name: 'new_name', age: 4 }, { name: 'name3', age: 5 } ]

次に、配列のネストされていない要素を変更すると、コピー元は変更されずに出力される。

let person = [
    1, 
    {name: 'name2', age: 4}, 
    {name: 'name3', age: 5}
];

let new_person =[...person]
//
new_person[0] = 3
console.log(person, new_person)

//出力値
[ 1, { name: 'name2', age: 4 }, { name: 'name3', age: 5 } ] 
[ 3, { name: 'name2', age: 4 }, { name: 'name3', age: 5 } ]

つまり、シャローコピーは深さ1のみをコピーし、ネストされた値を共有しないためには、要素の中身も再起的にコピーすることで完全に独立したコピーを作成しなければならない。

ディープコピー

ディープコピーとは、参照場所のデータを共有しない、完全に独立したコピーとなる。
そのため、コピーした値を変更するとコピー元にも影響が出る可能性は基本的にはない。

let person = [
    1, 
    {name: 'name2', age: 4}, 
    {name: 'name3', age: 5}
];

let new_person = JSON.parse(JSON.stringify(person))
new_person[1].name= 'new_name'

console.log(person, new_person)

//出力値
[ 1, { name: 'name2', age: 4 }, { name: 'name3', age: 5 } ] 
[ 1, { name: 'new_name', age: 4 }, { name: 'name3', age: 5 } ]

まとめ

今回はシャローコピーとディープコピーについてまとめてみた。
意外と基礎が疎かになっていることを最近発見してきているので、こういった知識をこれからなんとなくではなく、説明できるくらいには知識をつけていきたいと思う。

0
0
2

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
0
0