初心者向けのjQuery入門講座|デザイナー向けのJavaScriptライブラリ

このエントリーをはてなブックマークに追加
索引
Core:コアとなる仕組み
Selectors:セレクタ
Attributes:属性
Traversing:対象の変更
Manipulation:操作
CSS:スタイルシート
Events:イベント
Effects:演出効果
Ajax:xml等との連携
Utilities:ユーティリティ
Data:データ
Miscellaneous:諸々
Deferred:処理管理
Callbacks:コールバック
Internals:内部処理

jQuery.extend( )objectオブジェクトを連結

構文

objectオブジェクトを連結返値:objectオブジェクト
jQuery.extend( target [,object_1] [,object_N] )ver1.0〜
jQuery.extend( [deep,] target [,object_1] [,object_N] )ver1.1.4〜

機能

jQuery.extendメソッドを利用するとobjectオブジェクトを連結することができます。第1引数「deep」にtrueを設定することで、objectオブジェクト内にあるobjectオブジェクトも連結できます。

またjQuery.mergeメソッドと同じように引数「target」に設定したobjectオブジェクトも変更されてしまうことに注意してください。

引数「target」に空のobjectオブジェクトを設定することで、第2引数に設定したobjectオブジェクトの複製を得ることができます。そして、これを利用することで上記にある引数「target」に設定したobjectオブジェクトが変更される問題を回避できます。

上記構文には記載されていませんが、targetを省略してobjectオブジェクトを1つだけ設定すると、jQuery本体にobjectオブジェクトを追加できます。これを利用することでjQueryにオリジナルのメソッドを追加できます。
→ページ最下部の「メモ」を参照して下ださい。

解説

objectオブジェクトを連結します

サンプル(extend/01.html)を開いてbody内にbutton要素しかないことを確認して下さい。jQueryでは、まず以下の部分を確認してください。2つのobjectオブジェクト(appleObjとorangeObj)が作成され、3行目でjQuery.extendメソッドを利用してappleObjにorangeObjを連結しています。連結されたobjectオブジェクトは返値として返され、サンプルでは変数「extendObj」に代入しています。

var appleObj = {apple:100};
var orangeObj = {orange:10};
var extendObj = $.extend(appleObj, orangeObj);

続いて以下の部分を確認してください。buttonをクリックすると、本当にobjectオブジェクトが連結されているか確認するためにjQuery.eachメソッドappendメソッドを利用してobjectオブジェクト内のプロパティと、その値をbody要素に書き出すようにしています。

$("button").click(function(){
	$.each(extendObj, function (index, value){
		$("body").append(index + "の個数は" + value + "<br/>");
	});
});

結果として2つのプロパティ(appleとorange)の値が表示され、2つのobjectオブジェクトが連結されていることが確認できます。

元データも変更されてしまいます

jQuery.extendメソッドを利用すると、第1引数に設定した元データは他の引数のobjectオブジェクトと連結されてしまいます。サンプル(extend/02.html)を開いて、extend/01.htmlとほとんど同じ事を確認してください。

異なるのは以下の部分だけで、buttonをクリックした時にjQuery.eachメソッドで表示するobjectオブジェクトを「appleObj」に変更しただけです。

$.each(appleObj, function (index, value){
	$("body").append(index + "の個数は" + value + "
"); });

buttonをクリックするとorangeObjの内容が追加され、appleObjの内容が変更されてしまっているのが確認できます。返値で連結されたobjectオブジェクトが得られるのに何故このような仕様になったのでしょう?...。

objectオブジェクトを複製する

空のobjectオブジェクトと複製したいobjectオブジェクトを連結してobjectオブジェクトを複製することができます。オリジナルのobjectオブジェクトを残しておきたい時などに利用します。

サンプル(extend/03.html)を開いてbody内の構成がextend/01.htmlと同じ事を確認してください。jQueryでは、まず以下の部分を確認してください。1行目でobjectオブジェクト「oriObj」を作成し、2行目で空のobjectオブジェクトとoriObjを連結して新しいobjectオブジェクト「extendObj」を取得しています。そして3行目でextendObjのappleプロパティの値を50に変更しています。

var oriObj = {apple:100};
var extendObj = $.extend({ }, oriObj);
extendObj.apple = 50;

続いて以下の部分を確認してください。buttonをクリックするとappendメソッドを利用して、オリジナルのobjectオブジェクト「oriObj」と複製した「extendObj」のappleプロパティを表示するようにしています。

$("button").click(function(){
	$("body").append("oriObj.apple = " + oriObj.apple + "<br/>");
	$("body").append("extendObj.apple = " + extendObj.apple + "<br/>");
});

結果として、オリジナルのobjectオブジェクトに影響することなく複製したのobjectオブジェクトを変更できることが確認できます。

この結果は当たり前に思うかも知れませんが、objectオブジェクトは「参照の値渡し」のため、変数に代入しただけでは複製できません。サンプル(extend/03b.html)を開いてobjectオブジェクトの複製の部分が以下の様に変更されていることを確認してください(代入するだけに変更されています)。

var oriObj = {apple:100};
var extendObj = oriObj;
extendObj.apple = 50;

これでは3行目のextendObjの値を変更すると、オリジナルのoriObjの値も変更されてしまいます。buttonをクリックしてextendObjとoriObjのプロパティの値が同じになってしまっていることを確認してください。

引数のobjectオブジェクトを変更することなく連結する

extend/02.htmlでは引数「target」に設定したobjectオブジェクトも変更されてしまうことを説明しましたが、extend/03.htmlの「空のobjectオブジェクト」を利用することで問題を解決できます。

サンプル(extend/04.html)を開いてextend/01.htmlとほとんど同じ事を確認してください。異なるのは以下の点だけで、jQuery.extendメソッドの引数「target」の部分に空のobjectオブジェクトを設定しています。

var appleObj = {apple:100};
var orangeObj = {orange:10};
var extendObj = $.extend({}, appleObj, orangeObj);

buttonをクリックするとextend/01.htmlと同じ結果が表示され、extendObjは問題なく連結されていることが確認できます。

次にappleObjがextend/02.htmlと同じように変更されていないかを確認します。
サンプル(extend/04b.html)を開いて以下の部分を確認してください。extend/02.htmlと同様にjQuery.eachメソッドで表示するobjectオブジェクトを「appleObj」に変更しています。

$.each(appleObj, function (index, value){
	$("body").append(index + "の個数は" + value + "
"); });

buttonをクリックすると、appleの個数しか表示されないためappleObjは変更されていないことが確認できます。連結する際に各objectオブジェクトを変更したくない場合は、このテクニックを利用しましょう

ディープコピー

連結したいobjectオブジェクトの値がobjectオブジェクトだと思うような結果が得られません。
サンプル(extend/05.html)を開いてbody内の構成がextend/01.htmlと同じ事を確認してください。

jQueryは以下の様に連結するobjectオブジェクトが変更されています。ポイントは2つのobjectオブジェクトともプロパティ名が「orange」と同じ事です。

var weightObj = {orange:{weight: 30}};
var priceObj = {orange:{price: 100}};
var extendObj = $.extend(weightObj, priceObj);

この場合、プロパティ名が同じなので値(objectオブジェクト)が上書きされてしまいます。以下の処理では、それを確認するためのjQuery.eachメソッドで連結されたextendObj内にあるobjectオブジェクトである「orange」のプロパティを書き出すようにしています。

$("button").click(function(){
	$.each(extendObj.orange, function (index, value){
		$("body").append(index + "は" + value + "<br/>");
	});
});

結果として、buttonをクリックすると「priceは100」としか表示されません。これはプロパティ名がorangeと同じだったため、weightObjの値である「weight: 30」がpriceObjの値である「price: 100」に上書きされたためです。

しかしjQuery.extendメソッドの第1引数にtrueを設定すると、objectオブジェクト内にあるobjectオブジェクトも連結するようになります。サンプル(extend/05b.html)を開いて、extend/05.htmlと異なるのが以下の部分だけなのを確認してください。

var weightObj = {orange:{weight: 30}};
var priceObj = {orange:{price: 100}};
var extendObj = $.extend(true, weightObj, priceObj);

これでプロパティ名がorangeと同じだった場合でも値(objectオブジェクト)が上書きされずに連結されます。buttonをクリックするとproceの値とweightの値が表示され、深い場所のobjectオブジェクトも連結されたことが確認できます。

関連項目

配列を連結したり複製する場合はjQuery.mergeメソッドを利用してください。

メモ

jQueryにfunctionを追加する

本家のページではサンプルはないのですが、興味深い説明があったのでメモしておきます。それは引数のtargetは省略可能で、省略した場合はjQuery本体への追加となるそうです。これを利用すればjQueryに新しいメソッドを追加できます。

サンプル(extend/test01.html)を開いて以下の部分を確認してください。まず1行目で新規にobjectオブジェクト「testObj」を作成し、2行目で作成したtestObjにfunction「testFunc」を設定しています。処理内容は引数で受け取った値をアラートで表示するものになっています。

testObj = new Object();
testObj.testFunc = function (str){ alert(str) };
$.extend(testObj);

そして3行目でjQuery.extendメソッドの引数にtestObjだけを設定しています。こうすることでjQueryにobjectオブジェクトの内容(testFuncも含む)が追加されます。

実際に実行しているのは以下の部分です。buttonをクリックするとjQueryに追加されたfunction「testFunc」に引数「aaa」を渡して実行します。結果としてbuttonをクリックするとアラートで「aaa」と表示されます。

$("button").click(function(){
	$.testFunc("aaa");
});

objectオブジェクトはjQuery自身に追加されるので、上記のようにセレクタは設定できません

配列は連結できません

jQuery.extendメソッド3つ以上の引数を連結できるので、2つしか連結できないjQuery.mergeメソッドよりも便利です。なのでjQuery.extendメソッドでも配列が連結できればよいのですが...。できませんでした。

サンプル(extend/test02.html)を開いてjQueryを確認してください。以下の様に配列「arr_1」と「arr_2」をjQuery.extendメソッドで連結しようとしていますが、buttonをクリックしてもarr_1の値がそのまま表示され、処理されないことが確認できます。

var arr_1 = ["aaa", "bbb", "ccc"];
var arr_2 = ["ddd", "eee"];		
$(function () {
	$("button").click(function(){
		var ansArray = $.extend(arr_1, arr_2);
		$("body").append("<br/>" + "ansArray = " + ansArray);
	});
});