概要: このチュートリアルでは、浅いコピーと深いコピーを含むオブジェクトを JavaScript でコピーする方法を学びます。JavaScript でオブジェクトをコピーするには、3 つのオプションがあります。
- スプレッドシンタックス (
...
) を使用します。 Object.assign()
メソッドを使用します。JSON.stringify()
メソッドおよびJSON.parse()
メソッドを使用します。
以下は、上記 3 つのメソッドを使用してオブジェクトをコピーする方法を示しています。
const person = {
firstName: 'John',
lastName: 'Doe'
};
// using spread ...
let p1 = {
...person
};
// using Object.assign() method
let p2 = Object.assign({}, person);
// using JSON
let p3 = JSON.parse(JSON.stringify(person));
Code language: JavaScript (javascript)
スプレッドシンタックス (...
) と Object.assign()
の両方が浅いコピーを実行する一方、JSON メソッドは深いコピーを実行します。
浅いコピー 対 深いコピー
変数を使用した JavaScript では、プリミティブまたは参照になる値を格納します。変数に格納されている値のコピーを作成すると、同じ値を持つ新しい変数を作成します。プリミティブ値の場合、単純な代入を使用します。
let counter = 1;
let copiedCounter = counter;
Code language: JavaScript (javascript)
また、コピーされた変数の値を変更しても、元の値は同じままになります。
copiedCounter = 2;
console.log(counter);
Code language: JavaScript (javascript)
出力
1
ただし、参照値に代入演算子を使用すると、値はコピーされません。代わりに、両方の変数がメモリ内の同じオブジェクトを参照します。
let person = {
firstName: 'John',
lastName: 'Doe'
};
let copiedPerson = person;
Code language: JavaScript (javascript)
また、新しい変数 (copiedPerson) を介してオブジェクトにアクセスし、そのプロパティ (name) の値を変更すると、オブジェクトのプロパティの値を変更します。
copiedPerson.firstName = 'Jane';
console.log(person);
Code language: JavaScript (javascript)
出力
{
firstName: 'Jane',
lastName: 'Doe'
}
Code language: CSS (css)
深いコピーとは、新しい変数の値が元の変数から切断されることを意味し、浅いコピーとは、一部の値が元の変数にまだ接続されていることを意味します。
浅いコピーの例
次の例を考えてみましょう。
let person = {
firstName: 'John',
lastName: 'Doe',
address: {
street: 'North 1st street',
city: 'San Jose',
state: 'CA',
country: 'USA'
}
};
let copiedPerson = Object.assign({}, person);
copiedPerson.firstName = 'Jane'; // disconnected
copiedPerson.address.street = 'Amphitheatre Parkway'; // connected
copiedPerson.address.city = 'Mountain View'; // connected
console.log(copiedPerson);
Code language: JavaScript (javascript)
この例では、
- 1 番目に
person
という名前の新しいオブジェクトを作成します。 - 2 番目に
Object.assign()
メソッドを使用してperson
オブジェクトを複製します。 - 3 番目に
copiedPerson
オブジェクトのファーストネームと住所情報を変更します。
出力がここにあります。
{
firstName: 'Jane',
lastName: 'Doe',
address: {
street: 'Amphitheatre Parkway',
city: 'Mountain View',
state: 'CA',
country: 'USA'
}
}
Code language: CSS (css)
ただし、person オブジェクトの値を表示すると、住所情報は変更されましたがファーストネームには変更がありません。
console.log(person);
Code language: JavaScript (javascript)
出力
{
firstName: 'John',
lastName: 'Doe',
address: {
street: 'Amphitheatre Parkway',
city: 'Mountain View',
state: 'CA',
country: 'USA'
}
}
Code language: CSS (css)
その理由は、住所は参照値ですが、ファーストネームはプリミティブ値だからです。person
と copiedPerson
の両方が異なるオブジェクトを参照していますが、これらのオブジェクトは同じ address
オブジェクトを参照しています。
深いコピーの例
次のスニペットでは Object.assign()
メソッドを JSON メソッドに置き換えて、person
オブジェクトの深いコピーを実行します。
let person = {
firstName: 'John',
lastName: 'Doe',
address: {
street: 'North 1st street',
city: 'San Jose',
state: 'CA',
country: 'USA'
}
};
let copiedPerson = JSON.parse(JSON.stringify(person));
copiedPerson.firstName = 'Jane'; // disconnected
copiedPerson.address.street = 'Amphitheatre Parkway';
copiedPerson.address.city = 'Mountain View';
console.log(person);
Code language: JavaScript (javascript)
出力
{
firstName: 'John',
lastName: 'Doe',
address: {
street: 'North 1st street',
city: 'San Jose',
state: 'CA',
country: 'USA'
}
}
Code language: CSS (css)
この例では、copiedPerson
オブジェクト内のすべての値が元の person
オブジェクトから切断されています。このチュートリアルで、浅いコピーまたは深いコピーを使用して JavaScript でオブジェクトをコピーする方法を学習しました。