Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
AngularJS TIPS

AngularJS TIPS

複数のオブジェクトを結合するには?(extend/merge)

2016年5月9日

angular.extendメソッドを利用して、既存の複数のオブジェクトを結合する方法と注意事項を解説。また、入れ子になったオブジェクトを再帰的にマージする方法も説明する。

  • このエントリーをはてなブックマークに追加

 既存のオブジェクトを結合するには、AngularJSのグローバルAPIであるangular.extendメソッドを利用します。

[構文]extendメソッド

angular.extend(target, src, ……)

  • target: 結合先のオブジェクト
  • src: 結合するオブジェクト(結合元)

 さっそく、具体的な例を見てみましょう。以下は、あらかじめ用意されたメンバー情報member1member2member3extendメソッドで1つに束ねる例です。

HTML
<!DOCTYPE html>
<html ng-app>
<head>
<meta charset="UTF-8" />
<title>AngularJS</title>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<script>
var member1 = {
  name: '山田太郎',
  mail: 'yamada@example.com'
};

var member2 = {
  name: '山田花子',
  other: {
    history: 'WINGS大学卒',
    photo: 'face.png'
  }
};

var member3 = {
  other: {
    blood: 'A型'
  }
};

angular.extend(member1, member2, member3);
console.log(member1);
</script>
</body>
</html>
複数のオブジェクトを結合するコード(extend.html)
コンソール
{
  mail: "yamada@example.com",
  name: "山田花子",
  other: {
    blood: "A型"
  }
}
オブジェクトを結合した結果(開発者ツールで[Object]項目のツリーを展開して確認)

 extendメソッドは、一見して誤解のしようもない、シンプルなメソッドですが、利用する際には、いくつか注意すべき点もあります。

1同名のプロパティは、後のもので上書きされる

 この例であれば、変数member1member2ともにnameプロパティを持っていますので、後者の「山田花子」が優先されます。

2第1引数targetの内容を書き換える

 extendメソッドは、先頭のオブジェクト(引数target)の内容を書き換えます。よって、もしも元のオブジェクトに影響を及ぼしたくない場合には、太字の部分を以下のように書き換えてください。

JavaScript
var extended = angular.extend({}, member1, member2, member3);
console.log(extended);  // オブジェクトが結合された結果
console.log(member1);   // member1の内容は変わっていない
元のオブジェクトに影響を与えずに、複数のオブジェクトを結合するテクニック
3再帰的な結合には対応していない

 この例であれば、変数member2member3でそれぞれ定義されたotherプロパティに注目です。サブプロパティとして、それぞれhistoryphotobloodプロパティを持っていますが、extendメソッドではこれらを再帰的には結合しません。

 そのまま後者のオブジェクトmember3otherプロパティが優先され、member2otherプロパティは置き換えられてしまう点に注意してください。

 もしも入れ子となったオブジェクトまで再帰的にマージするのであれば、extendメソッドではなく、mergeメソッドを利用します。mergeメソッドの構文は、extendメソッドと同じです。

 以下は、太字部分をmergeメソッドで書き換えたコードと、その結果です。

JavaScript
angular.merge(member1, member2, member3);
複数のオブジェクトを再帰的に結合するコード(extend.html)
コンソール
{
  mail: "yamada@example.com",
  name: "山田花子",
  other: {
    history: "WINGS大学卒",
    photo: "face.png",
    blood: "A型"
}
オブジェクトを結合した結果(開発者ツールから確認)

 確かに、otherプロパティの内容が再帰的に結合されていることが確認できます。

処理対象:オブジェクト結合 カテゴリ:サービス
API:angular.extend|angular.merge カテゴリ:ng(コアモジュール) > function(関数)

※以下では、本稿の前後を合わせて5回分(第53回~第57回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

AngularJS TIPS
53. 配列/オブジェクトをコピーするには?(copy)

配列のコピーで、JavaScript標準のconcatメソッドを使う場合とAngularJSのcopyメソッドを使う場合の違いを説明。シャローコピーとディープコピーとは?

AngularJS TIPS
54. コンテンツ・セキュリティ・ポリシーを利用する(ng-csp)

セキュリティフレームワーク「CSP」による制限ポリシーを有効にした場合に、AngularJSでは特定のケースでエラーとなる。そのケースの内容と回避方法を解説する。

AngularJS TIPS
55. 【現在、表示中】≫ 複数のオブジェクトを結合するには?(extend/merge)

angular.extendメソッドを利用して、既存の複数のオブジェクトを結合する方法と注意事項を解説。また、入れ子になったオブジェクトを再帰的にマージする方法も説明する。

AngularJS TIPS
56. AngularJSの管理外でサービスを注入するには?($injector)

AngularJSの管理外でも、$injectorサービスを使ってサービスを手動でインスタンス化することで、AngularJSが提供するサービスを利用できる。その基本的な利用方法を説明する。

AngularJS TIPS
57. $injectorサービスでサービスの取得/存在確認を行うには?($injector)

AngularJSの管理外でサービスを手動でインスタンス化して利用できる$injectorサービスの応用的な活用方法として、has/get/instantiateメソッドを解説する。

サイトからのお知らせ

Twitterでつぶやこう!