JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

Lodashの.extend()/.assign()と.merge()の違いを徹底解説!浅いコピーと再帰的マージの使い分け

JavaScriptでオブジェクトを扱う際、Lodashの_.assign()(または_.extend())と_.merge()はどちらもオブジェクトを結合するためのメソッドですが、その動作には重要な違いがあります。この記事では、両者の違いを具体例とともにわかりやすく解説します。

_.assign() / _.extend() の動作:浅いコピー(シャローコピー)

assignextendは、ソースオブジェクトの各プロパティを取り出し、その値をそのままデスティネーション(コピー先)にコピーします。

ポイントは、プロパティの値がそれ自体オブジェクトだった場合でも、その中身を再帰的にたどらないという点です。つまり、ネストされた子オブジェクトごと丸ごと参照がコピーされます。この方式は「浅いコピー(シャローコピー/シャロークローン)」と呼ばれます。

結果として、デスティネーションに同名のプロパティがある場合、その値はソース側の値で完全に上書きされます。

_.merge() の動作:再帰的なディープマージ

一方、mergeは、ソースオブジェクトの各プロパティについて、「その値がオブジェクト自身かどうか」をチェックします。

もしオブジェクトであれば、再帰的に処理を進め、子オブジェクトのプロパティ同士をソースからデスティネーションへ対応付けて統合します。これにより、ネストされた構造を持つオブジェクトでも、階層を保ったまま内容をマージできます。この方式は「ディープマージ(深い結合)」と呼ばれます。

コード例

実際のコードで違いを見てみましょう。

let _ = require('lodash');
let destination = {
    a: {
        b: 1,
        c: 2
    },
};
let source = {
    a: {
        d: 2,
        c: 3
    },
};
console.log(_.merge(destination, source));
console.log(_.extend(destination, source));

出力結果

このコードを実行すると、以下の出力が得られます。

{ a: { b: 1, c: 3, d: 2 } }
{ a: { d: 2, c: 3 } }

結果のポイント

mergeでは、aの中のプロパティが再帰的に統合され、bcdすべてが保持されています(cはソース側の値3で上書き)。一方、extendでは、aの値がソース側のオブジェクトで丸ごと置き換えられているため、デスティネーション側にあったb: 1は失われています。

使い分けの目安

  • _.assign() / _.extend():フラットなオブジェクトの結合や、単純にプロパティを上書きしたい場合に最適。処理も高速です。
  • _.merge():設定オブジェクトのようなネストされたデータ構造を統合したい場合に最適。既存の階層構造を壊さずにマージできます。

ネストされたオブジェクトを扱う場合は、意図しないデータ損失を避けるために、mergeを使うのが安全です。

  1. C#と.NETの違いをわかりやすく解説!言語とフレームワークの関係

    C#と.NETの基本的な違いC#(シーシャープ)はマイクロソフトが開発したプログラミング言語であり、一方の.NET(ドットネット)はアプリケーション開発を支援するフレームワークです。この2つは密接な関係にありますが、それぞれの役割はまったく異なります。.NETの中核となる「共通言語ランタイム(CLR)」.NETには「共通言語ランタイム(CLR:Common Language Runtime)」と呼ばれる仮想的な実行環境が組み込まれています。CLRはメモリ管理、例外処理、セキュリティなどを担当し、.NET上で動作するすべてのアプリケーションの土台となる重要なコンポーネントです。C#だけじゃない!

  2. GoとJavaの違いを徹底比較!特徴と使い分けのポイント

    プログラミング言語を選ぶ際、「Go」と「Java」のどちらを採用すべきか迷う開発者は少なくありません。どちらもGoogleや企業システムで広く使われる人気言語ですが、設計思想や言語仕様には大きな違いがあります。本記事では、それぞれの言語の特徴を解説したうえで、両者の主な違いを比較表を使ってわかりやすく整理します。 GoとはGoはGoogleが開発した手続き型(プロシージャル)プログラミング言語です。プログラムはパッケージ単位で構成され、シンプルで読みやすいコード記述を重視した設計になっています。動的言語に近い柔軟なパターンを取り入れつつ、静的型付けによる安全性も兼ね備えています。また、軽量スレ