javascriptのオブジェクトを再生するには、深いコピー、浅いコピー
8643 ワード
cxiのコピー、浅いコピーを討論するブログをよく見ますが、最近はjsの方が多くて、jsの相手のコピーをしに来ました.
以下はウィキペディアの深さコピーに対する説明です.
浅いコピー
One method of copying an object is the show copy.In the process of show copying A,B will copy all of A's field values. If the field value is a memory address it copis the memory address,and if the field value is a prmitive type it copies the value of the prmitive type.
The disadvid antage is if you modify the memory address of B's fields point to,you are also modifying what A's fields point to.
一つのコピー対象の方式は浅いコピーで、浅いコピー対象Aの場合、対象BはAのすべてのフィールドをコピーします.フィールドがメモリアドレスなら、Bはアドレスをコピーします.もしフィールドがベースタイプなら、Bはその値をコピーします.
浅いコピーの欠点は、オブジェクトBが指すメモリアドレスを変更すると、オブジェクトAがこのアドレスを指すフィールドを変更することです.
コピー
An alternative is a deep copy.Here the data is actually copied over.The reult is different from the result a show copy gives.The advantage is that A and B dot depedipend on and the cospland cosland.
もう一つは、深くコピーして、このようにすべてのデータを完全にコピーします.利点はBとAは相互依存しないことです.(A、Bは完全に関連しています.)欠点はコピーのスピードが遅いことです.価格がもっと大きいです.
C〓の中の対象はコピーします.
cxiの中の浅いコピー
CヒドイObjectベースではプロテctedの浅いコピー関数を定義しています.以下はテストコードです.
私たちは、プログレッシブとアンチプログレッシブを利用して、簡単に深いコピーを実現することができます.c獞の中ではオプションのプログレッシブ方法がたくさんあります.例えば、BinaryFormater、XML serializer、JSON serializer ,この文章は主にjsのものですから、多く紹介します.
javascriptもコピーしに来ます.
javascript浅いコピー対象
ここでは上のc舸personオブジェクトをjsonオブジェクトに翻訳します.age:5,address:{zipcode:'200000',city:'shanghai'}
jsでは、浅いコピーが一般的ではないので、以下のようにテストできます.
jsの深度コピーを実現するのも簡単です.浅いコピーをもとに、現在の反復のフィールドが非nullのobjectオブジェクトであるかどうかを判断します.もし、再帰的には浅いコピーで処理します.以上のように、配列オブジェクトを考慮して、js版のコピー関数を自分で書きました.
1.対象がnullかどうか、undefinedか、または非objectのオブジェクトかどうかを判断する場合、直接に対象に戻ります.
2. オブジェクトが配列かどうかを判断し、深いコピーを指定すると、配列オブジェクトを巡回し、そのメンバーを深くコピーします.深いコピーに指定していない場合は、直接に配列に戻ります.
3. 配列されていないオブジェクトであれば、メンバを巡回して、メンバオブジェクトを再帰的に処理し、最後にコピーを返します.
以下はウィキペディアの深さコピーに対する説明です.
浅いコピー
One method of copying an object is the show copy.In the process of show copying A,B will copy all of A's field values. If the field value is a memory address it copis the memory address,and if the field value is a prmitive type it copies the value of the prmitive type.
The disadvid antage is if you modify the memory address of B's fields point to,you are also modifying what A's fields point to.
一つのコピー対象の方式は浅いコピーで、浅いコピー対象Aの場合、対象BはAのすべてのフィールドをコピーします.フィールドがメモリアドレスなら、Bはアドレスをコピーします.もしフィールドがベースタイプなら、Bはその値をコピーします.
浅いコピーの欠点は、オブジェクトBが指すメモリアドレスを変更すると、オブジェクトAがこのアドレスを指すフィールドを変更することです.
コピー
An alternative is a deep copy.Here the data is actually copied over.The reult is different from the result a show copy gives.The advantage is that A and B dot depedipend on and the cospland cosland.
もう一つは、深くコピーして、このようにすべてのデータを完全にコピーします.利点はBとAは相互依存しないことです.(A、Bは完全に関連しています.)欠点はコピーのスピードが遅いことです.価格がもっと大きいです.
C〓の中の対象はコピーします.
cxiの中の浅いコピー
CヒドイObjectベースではプロテctedの浅いコピー関数を定義しています.以下はテストコードです.
public class Address
{
public string ZipCode { get; set; }
public string City { get; set; }
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Address Address { get; set; }
/// <summary>
///
/// </summary>
/// <returns></returns>
public Person Clone()
{
return this.MemberwiseClone() as Person;
}
}
class Program
{
static void Main(string[] args)
{
Person p = new Person();
p.Name = "leon";
p.Age = 5;
p.Address = new Address
{
ZipCode = "200000",
City = "Shanghai"
};
Person copy = p.Clone();
copy.Address.City = "beijing";
Console.WriteLine(p.Address.City); // print beijing
Console.Read();
}
}
cxiの中の深コピー私たちは、プログレッシブとアンチプログレッシブを利用して、簡単に深いコピーを実現することができます.c獞の中ではオプションのプログレッシブ方法がたくさんあります.例えば、BinaryFormater、XML serializer、JSON serializer ,この文章は主にjsのものですから、多く紹介します.
javascriptもコピーしに来ます.
javascript浅いコピー対象
ここでは上のc舸personオブジェクトをjsonオブジェクトに翻訳します.age:5,address:{zipcode:'200000',city:'shanghai'}
jsでは、浅いコピーが一般的ではないので、以下のようにテストできます.
function shallowCopy( o )
{
var copy = {};
for ( var i in o )
{
copy[i] = o[i];
}
return copy;
}
javascriptオブジェクトを深くコピーします.jsの深度コピーを実現するのも簡単です.浅いコピーをもとに、現在の反復のフィールドが非nullのobjectオブジェクトであるかどうかを判断します.もし、再帰的には浅いコピーで処理します.以上のように、配列オブジェクトを考慮して、js版のコピー関数を自分で書きました.
function cloneObject( o, d )
{
if ( o === null || o === undefined || typeof ( o ) !== 'object' )
{
return o;
}
var deep = !!d;
var cloned;
if ( o.constructor === Array )
{
if ( deep === false )
{
return o;
}
cloned = [];
for ( var i in o )
{
cloned.push( cloneObject( o[i], deep ) );
}
return cloned;
}
cloned = {};
for ( var i in o )
{
cloned[i] = deep ? cloneObject( o[i], true ) : o[i];
}
return cloned;
}
ここで、oはコピーされる対象であり、dは深くコピーするかどうかを指定しています. 1.対象がnullかどうか、undefinedか、または非objectのオブジェクトかどうかを判断する場合、直接に対象に戻ります.
2. オブジェクトが配列かどうかを判断し、深いコピーを指定すると、配列オブジェクトを巡回し、そのメンバーを深くコピーします.深いコピーに指定していない場合は、直接に配列に戻ります.
3. 配列されていないオブジェクトであれば、メンバを巡回して、メンバオブジェクトを再帰的に処理し、最後にコピーを返します.