ネストされたオブジェクトとは?
JavaScriptでは、オブジェクトの中に別のオブジェクトを含むことができ、これをネストされたオブジェクトと呼びます。ネストされたオブジェクトは、データを階層的に整理するのに便利で、複雑な構造を持つデータの扱いに使われます。しかし、ネストされたオブジェクトのマージやコピーには特別な処理が必要になる場合があります。
ネストされたオブジェクトの基本的な操作
ネストされたオブジェクトにアクセスするには、ドット(.
)またはブラケット([]
)記法を使ってアクセスします。深くネストされたオブジェクトには複数のアクセス方法があり、正確なパスを指定する必要があります。
ネストされたオブジェクトのアクセス例
const user = {
name: "Taro",
address: {
city: "Tokyo",
postalCode: "123-4567"
}
};
console.log(user.address.city); // "Tokyo"
console.log(user["address"]["postalCode"]); // "123-4567"
この例では、user
オブジェクト内のaddress
オブジェクトにアクセスしています。ドット記法とブラケット記法の両方を使うことができます。
ネストされたオブジェクトのマージ
ネストされたオブジェクトをマージする際、単純にObject.assign()
やスプレッド構文を使うと、ネストされた部分が正しくマージされず、上書きされてしまう可能性があります。深いネストされたオブジェクトを適切にマージするには、再帰的な処理やカスタムの関数を使う必要があります。
単純なマージの問題点
const obj1 = {
name: "Taro",
address: {
city: "Tokyo",
postalCode: "123-4567"
}
};
const obj2 = {
address: {
city: "Osaka"
}
};
const mergedObj = { ...obj1, ...obj2 };
console.log(mergedObj);
// { name: "Taro", address: { city: "Osaka" } }
この例では、obj2
のaddress
オブジェクトがobj1
のaddress
オブジェクトを完全に上書きしてしまい、postalCode
プロパティが失われています。
再帰的なマージの方法
ネストされたオブジェクトを正しくマージするためには、再帰的に処理を行い、各レベルのオブジェクトを一つずつマージしていく必要があります。再帰的なマージを行うカスタム関数を作成することで、深くネストされたオブジェクトのプロパティを保持しながらマージすることが可能です。
再帰的なマージ関数の例
function mergeDeep(target, source) {
for (const key in source) {
if (source[key] instanceof Object && key in target) {
Object.assign(source[key], mergeDeep(target[key], source[key]));
}
}
return { ...target, ...source };
}
const obj1 = {
name: "Taro",
address: {
city: "Tokyo",
postalCode: "123-4567"
}
};
const obj2 = {
address: {
city: "Osaka"
}
};
const mergedObj = mergeDeep(obj1, obj2);
console.log(mergedObj);
// { name: "Taro", address: { city: "Osaka", postalCode: "123-4567" } }
この例では、mergeDeep
という関数を使って再帰的にオブジェクトをマージしています。address
オブジェクト内のcity
が更新されつつ、postalCode
は保持されています。
ネストされたオブジェクトのコピー
オブジェクトをコピーする際、浅いコピーと深いコピーの違いに注意する必要があります。浅いコピーでは、ネストされたオブジェクトが参照でコピーされるため、元のオブジェクトが変更される可能性があります。深いコピーでは、ネストされたオブジェクトも含めて全てのプロパティが新しいオブジェクトとしてコピーされます。
浅いコピーと深いコピーの違い
浅いコピー | 深いコピー |
---|---|
プロパティの第一層のみをコピー | 全ての階層を再帰的にコピー |
ネストされたオブジェクトは参照でコピー | ネストされたオブジェクトも新しいオブジェクトとしてコピー |
浅いコピーの例
const original = {
name: "Taro",
address: {
city: "Tokyo",
postalCode: "123-4567"
}
};
const shallowCopy = { ...original };
shallowCopy.address.city = "Osaka";
console.log(original.address.city); // "Osaka"
この例では、shallowCopy
を使ってオブジェクトを浅くコピーしていますが、address
オブジェクトが参照でコピーされているため、shallowCopy
を変更するとoriginal
も変更されています。
深いコピーの例
const original = {
name: "Taro",
address: {
city: "Tokyo",
postalCode: "123-4567"
}
};
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.address.city = "Osaka";
console.log(original.address.city); // "Tokyo"
この例では、JSON.stringify
とJSON.parse
を使ってオブジェクトを深くコピーしています。deepCopy
の変更はoriginal
に影響を与えていません。
まとめ
ネストされたオブジェクトを処理する際、浅いマージやコピーでは不十分な場合があります。再帰的なマージを行うことで、深くネストされたプロパティを保持しながらオブジェクトを結合できます。また、深いコピーを行うことで、オブジェクトの完全な複製が可能となり、元のオブジェクトへの影響を避けることができます。