TypeScriptでオブジェクトを浅くコピーする方法:スプレッド演算子 vs Object.assign()
TypeScriptにおけるスプレッド演算子
配列の展開
スプレッド演算子を用いると、既存の配列に新しい要素を追加したり、複数の配列を結合したりすることができます。
例:
const numbers1 = [1, 2, 3];
const numbers2 = [4, 5];
const combinedNumbers = [...numbers1, ...numbers2];
console.log(combinedNumbers); // 出力: [1, 2, 3, 4, 5]
この例では、numbers1
と numbers2
の要素をすべて combinedNumbers
という新しい配列に結合しています。
オブジェクトの展開
スプレッド演算子を用いると、既存のオブジェクトのプロパティを新しいオブジェクトにコピーしたり、複数のオブジェクトをマージしたりすることができます。
const person1 = { name: "Alice", age: 30 };
const person2 = { city: "Seattle" };
const completePerson = { ...person1, ...person2 };
console.log(completePerson); // 出力: { name: 'Alice', age: 30, city: 'Seattle' }
この例では、person1
と person2
のプロパティをすべて completePerson
という新しいオブジェクトにマージしています。
- スプレッド演算子は、浅いコピーしか行いません。つまり、オブジェクト内のプロパティが参照型の場合、元のオブジェクトと新しいオブジェクトで同じオブジェクトを参照することになります。
- スプレッド演算子は、キーの競合を解決しません。複数のオブジェクトをマージする場合、同じキーを持つプロパティが存在すると、最後のオブジェクトのプロパティが優先されます。
スプレッド演算子は、関数への引数の渡し方や、ジェネリック型における型推論など、様々な用途で使用することができます。
スプレッド演算子は、TypeScriptにおける便利な演算子であり、様々な場面で活用することができます。構文自体はシンプルですが、使いこなすことで、コードをより簡潔かつ表現力豊かにすることができます。
TypeScript スプレッド演算子を使ったサンプルコード
例1:配列の要素を追加・結合
const numbers1 = [1, 2, 3];
const numbers2 = [4, 5];
// 新しい要素を追加
const numbersWithZero = [...numbers1, 0];
console.log(numbersWithZero); // 出力: [1, 2, 3, 0]
// 複数の配列を結合
const combinedNumbers = [...numbers1, ...numbers2, 6];
console.log(combinedNumbers); // 出力: [1, 2, 3, 4, 5, 6]
例2:オブジェクトのプロパティをコピー・マージ
const person1 = { name: "Alice", age: 30 };
const person2 = { city: "Seattle", job: "Software Engineer" };
// 新しいオブジェクトを作成
const completePerson = { ...person1, ...person2 };
console.log(completePerson); // 出力: { name: 'Alice', age: 30, city: 'Seattle', job: 'Software Engineer' }
// プロパティを更新
const updatedPerson = { ...person1, age: 35 };
console.log(updatedPerson); // 出力: { name: 'Alice', age: 35, city: 'Seattle', job: 'Software Engineer' }
例3:関数への引数の渡し方
function sumNumbers(numbers: number[]): number {
return numbers.reduce((total, num) => total + num, 0);
}
const numbers = [1, 2, 3, 4, 5];
const sum = sumNumbers([...numbers]);
console.log(sum); // 出力: 15
例4:ジェネリック型における型推論
function mergeArrays<T>(arr1: T[], arr2: T[]): T[] {
return [...arr1, ...arr2];
}
const numbers: number[] = mergeArrays([1, 2, 3], [4, 5, 6]);
const strings: string[] = mergeArrays(["Alice", "Bob"], ["Charlie", "David"]);
console.log(numbers); // 出力: [1, 2, 3, 4, 5, 6]
console.log(strings); // 出力: ["Alice", "Bob", "Charlie", "David"]
これらの例は、スプレッド演算子の基本的な使い方を示すものです。より複雑なシナリオでは、スプレッド演算子を他の構文と組み合わせることで、より柔軟なコードを書くことができます。
補足
- スプレッド演算子は、TypeScript 2.1以降で使用できます。
TypeScriptにおけるスプレッド演算子の代替方法
const numbers1 = [1, 2, 3];
const numbers2 = [4, 5];
const combinedNumbers = numbers1.concat(numbers2);
console.log(combinedNumbers); // 出力: [1, 2, 3, 4, 5]
slice()
メソッド:既存の配列の一部を切り取ったり、新しい要素を挿入したりする際に使用できます。
const numbers = [1, 2, 3, 4, 5];
const numbersWithZero = [...numbers.slice(0, 3), 0, ...numbers.slice(3)];
console.log(numbersWithZero); // 出力: [1, 2, 3, 0, 4, 5]
オブジェクトのプロパティをコピー・マージ
- オブジェクトリテラル:新しいオブジェクトを作成したり、既存のオブジェクトのプロパティを更新したりする際に使用できます。
const person1 = { name: "Alice", age: 30 };
const person2 = { city: "Seattle", job: "Software Engineer" };
const completePerson = { ...person1, ...person2 };
console.log(completePerson); // 出力: { name: 'Alice', age: 30, city: 'Seattle', job: 'Software Engineer' }
Object.assign()
メソッド:既存のオブジェクトに新しいプロパティを追加したり、既存のプロパティを更新したりする際に使用できます。
const person1 = { name: "Alice", age: 30 };
const person2 = { city: "Seattle", job: "Software Engineer" };
const completePerson = Object.assign({}, person1, person2);
console.log(completePerson); // 出力: { name: 'Alice', age: 30, city: 'Seattle', job: 'Software Engineer' }
- forループ:配列やオブジェクトを反復処理し、要素を個別に処理する際に使用できます。
const numbers = [1, 2, 3, 4, 5];
const numbersWithZero = [];
for (let num of numbers) {
if (num !== 3) {
numbersWithZero.push(num);
} else {
numbersWithZero.push(0);
}
}
console.log(numbersWithZero); // 出力: [1, 2, 0, 4, 5]
これらの代替方法は、それぞれ異なる長所と短所があります。状況に応じて適切な方法を選択することが重要です。
スプレッド演算子は、簡潔で表現力豊かなコードを書くための便利なツールですが、万能ではありません。状況によっては、他の方法の方が適切な場合があります。上記で紹介した代替方法を理解することで、より柔軟で効率的なコードを書くことができます。
typescript