Edited at

jQuery 1.1.4 以降のextendの挙動を調べたYO

More than 5 years have passed since last update.

jQueryのextendのオプションの挙動がよくわからなかったのでまとめました。

http://api.jquery.com/jquery.extend/

まずは4種類のオブジェクトを用意します。

var deepObject1 = {

x: 200,
y: 1000
}

var deepObject2 = {
a: 777,
b: 999
}

var target = {
a: 1,
b: 2,
y: deepObject1
}

var object1 = {
a: 'object1',
x: 100,
y: deepObject2
}

これらのオブジェクトに対してextendを色々していきます。


deepオプションfalseの場合

var hoge = $.extend(false,target,object1);

object1.a = 0000000;

console.log(hoge);
console.log(target);
console.log(object1);


結果は

[object Object] {

a: "object1",
b: 2,
x: 100,
y: [object Object] {
a: 777,
b: 999
}
}
[object Object] {
a: 1,
b: 2,
y: [object Object] {
x: 200,
y: 1000
}
}
[object Object] {
a: 0,
x: 100,
y: [object Object] {
a: 777,
b: 999
}
}

hogeに2つのオブジェクトが結合されたものができています。

hogeオブジェクトのyフィールドにはdeepObject2が入っています。最後の引数が優先されました。

もともとのオブジェクトは変化していません。

また、あとからいじったobject1への変更はhogeには反映されていません。


deepオプションtrueの場合

var hoge = $.extend(true,target,object1);

object1.a = 0000000;

console.log(hoge);
console.log(target);
console.log(object1);


結果は

[object Object] {

a: "object1",
b: 2,
x: 100,
y: [object Object] {
a: 777,
b: 999,
x: 200,
y: 1000
}
}
[object Object] {
a: "object1",
b: 2,
x: 100,
y: [object Object] {
a: 777,
b: 999,
x: 200,
y: 1000
}
}
[object Object] {
a: 0,
x: 100,
y: [object Object] {
a: 777,
b: 999
}
}

hogeとtargetが同じになっているのがわかります。

deep=trueにするとtarget自体が拡張されるということのようです。

またこちらもあとから変更したobject1の状態は他のオブジェクトに反映されていません。

つまりいわゆるディープコピー・シャローコピーのディープコピーのことではないようです。

ただし、hogeとtargetどちらのyフィールドもdeepObject1がdeepObject2で拡張されているのがわかります。

どうやら再帰的に拡張してくれるようです。


deepオプション無しのextend

var hoge = $.extend(target,object1);

object1.a = 0000000;

console.log(hoge);
console.log(target);
console.log(object1);


結果は

[object Object] {

a: "object1",
b: 2,
x: 100,
y: [object Object] {
a: 777,
b: 999
}
}
[object Object] {
a: "object1",
b: 2,
x: 100,
y: [object Object] {
a: 777,
b: 999
}
}
[object Object] {
a: 0,
x: 100,
y: [object Object] {
a: 777,
b: 999
}
}

こちらはhogeとtargetは同じになっていますが、yフィールドは再帰的には拡張されていません。

もちろんあとから変更したobject1の状態は他のオブジェクトに反映されていません。


まとめると

extend
target自身の拡張
再帰的な拡張

deepオプションfalseの場合
されない
しない

deepオプションtrueの場合
される
する

deepオプション無しのextend
される
しない

以上