プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • JavaScript
  • 【JavaScript】「シャローコピー」と「ディープコピー」とは
 
 
     
  • サーバー言語  
    • Python
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【JavaScript】「シャローコピー」と「ディープコピー」とは

09.05

  • miyabisan2
  • コメントを書く

この記事は1分で読めます

JavaScriptのオブジェクトのメモリの仕組み

JavaScriptはオブジェクトの変数をメモリに格納する場合は番地のみ格納する仕様になっています。なので、オブジェクトの中身をコピーしたい場合はシャローコピーやディープコピーなどの概念を理解する必要があります。

そもそもなぜオブジェクトは番地のみが格納されるのか?

オブジェクトは複数の値を保持することが普通なのでいちいち値を移していたら非常に時間がかかってしまうためです。なのでデフォルトではJSではオブジェクトは番地情報のみ変数に格納する仕様になっています。

シャローコピー

スプレット構文

なお、配列の操作であれば、concatでも同じようなことはできますが、基本的にスプレット構文の方が速いらしいので、スプレット構文を使った方が良さそうです。

例

1
2
3
const a = {a:1,b:2}
const b = {c:3,d:4}
const spread = {...a,...b} //{a: 1, b: 2, c: 3, d: 4}

Object.assign

例

1
2
3
const a = {a:1,b:2}
const b = {c:3,d:4}
const assign = Object.assign({},a,b) //{a: 1, b: 2, c: 3, d: 4}

シャローコピーの欠点

オブジェクトの2階層以降はメモリ位置のみのコピーになってしまう。

1
2
3
4
5
6
7
8
9
10
11
const a = {a:1,b:{b2:5}}
const b = Object.assign({},a)
b.a = 9
b.b.b2 = 7
console.log(a)
{
    "a": 1, // こちらは書き換わらない。
    "b": {
        "b2": 7 // 書き変わってしまう。
    }
}

ディープコピー

JSON.parseとJSON.stringify

一度jsonに展開してまたオブジェクトに戻します。こうすればディープコピーを実現できます。

jsonでディープコピーする場合の落とし穴

一度jsonにする都合上、関数やundefinedが消滅してしまう。(関数という概念はjsonには存在しないため)

階層をつけてシャローコピーする。

1
2
3
4
5
6
7
const a = {a:1,b:{b2:5}}
const b = {
    "a": 1,
    "b": {
        ...a.b
    }
}

こうすれば実質的にディープコピーになります。ただ、オブジェクトのプロパティが増えれば増えるほど冗長になるという欠点はあります。

その他

Reactなどではimmer.jsなどを使って簡単にイミュータブルな処理を実装してくれます。

ではなぜシャローコピーという概念があるのか?

ディープコピーに比べてコストがかからないためです。できるだけシャロコピーで済むものはシャロコピーで済ませるのが吉です。

スポンサーリンク
  • 2021 09.05
  • miyabisan2
  • コメントを書く
  • JavaScript
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2023 09.28

    StoryBookの基本

  2. 2018 07.05

    【JavaScript】変数のスコープについて

  3. 2018 04.12

    【JavaScript】「コールバック関数」や、「コールバック地獄」について

  4. 2020 04.26

    【JavaScript】「配列」、「lodash」の活用

  5. 2018 04.29

    【HTML】HTML5の影響(JavaScriptや追加タグなど)

  6. 2021 05.01

    【JavaScript】for文、繰り返し文、配列系メソッドの使い分け

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【関数型言語】「参照透過性」を破壊するものと対策

【Redux】「正規化」について

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • AngularJS
  • API
  • AWS
  • C++
  • CSS
  • cursor
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Figma
  • Git
  • GitLab
  • GraphQL
  • gRPC
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 生成AI
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー