概要: このチュートリアルでは、ES2018 で導入された JavaScript のオブジェクトスプレッド構文 (...
) を使用して、オブジェクトのクローンを作成したり、複数のオブジェクトを 1 つにマージする方法を学習します。
JavaScript オブジェクトスプレッド演算子の概要
ES6 では、スプレッド演算子 (...
) を使用して、配列の要素を展開します。スプレッド演算子は、配列のクローンを作成するのに非常に役立ちます。例えば
let colors = ['red', 'green', 'blue'];
let rgb = [...colors];
console.log(rgb);
Code language: JavaScript (javascript)
出力
[ 'red', 'green', 'blue' ]
Code language: JSON / JSON with Comments (json)
この例では、スプレッド演算子 (...
) は colors
配列の要素を展開し、新しい配列 rgb
に配置します。スプレッド演算子 (...
) は、次の例に示すように、2 つ以上の配列を 1 つにマージするためにも使用できます。
let rgb = [ 'red', 'green', 'blue' ];
let cmyk = ['cyan', 'magenta', 'yellow', 'black'];
let merge = [...rgb, ...cmyk];
console.log(merge);
Code language: JavaScript (javascript)
出力
[ 'red', 'green', 'blue', 'cyan', 'magenta', 'yellow', 'black' ]
Code language: JSON / JSON with Comments (json)
ES2018 では、スプレッド演算子 (...
) が拡張され、オブジェクトの独自の 列挙可能なプロパティでも動作するようになりました。 radius
プロパティを持つ circle
オブジェクトがあるとします。
const circle = {
radius: 10
};
Code language: JavaScript (javascript)
次の例では、スプレッド演算子 (...
) を使用して、circle
オブジェクトのすべてのプロパティと追加のプロパティ color
を持つ coloredCircle
オブジェクトを作成します。
const coloredCircle = {
...circle,
color: 'black'
};
console.log(coloredCircle);
Code language: JavaScript (javascript)
出力
{
radius: 10,
color: 'black'
}
Code language: CSS (css)
JavaScript オブジェクトスプレッド演算子のユースケース
1) オブジェクトのクローン作成
スプレッド演算子を使用して、オブジェクトの独自の列挙可能なプロパティのクローンを作成できます。
const circle = {
radius: 10
};
const clonedCircle = {...circle};
console.log(clonedCircle);
Code language: JavaScript (javascript)
出力
{ radius: 10 }
Code language: CSS (css)
クローンは常に浅いコピーであることに注意してください。例えば
const circle = {
radius: 10,
style: {
color: 'blue'
}
};
const clonedCircle = {
...circle
};
clonedCircle.style = 'red';
console.log(clonedCircle);
Code language: JavaScript (javascript)
出力
{ radius: 10, style: 'red' }
Code language: CSS (css)
2) オブジェクトのマージ
配列と同様に、スプレッド演算子 (...
) を使用して 2 つのオブジェクトをマージできます。
const circle = {
radius: 10
};
const style = {
backgroundColor: 'red'
};
const solidCircle = {
...circle,
...style
};
console.log(solidCircle);
Code language: JavaScript (javascript)
出力
{ radius: 10, backgroundColor: 'red' }
Code language: CSS (css)
スプレッド演算子と Object.assign() の比較
スプレッド演算子 (...
) はターゲットオブジェクトに新しいプロパティを定義しますが、Object.assign()
メソッドはそれらを割り当てます。これには 2 つの副作用があります。
1) セッターを持つターゲットオブジェクト
Object.assign()
はターゲットオブジェクトのセッターを呼び出しますが、スプレッド演算子は呼び出しません。以下は、Object.assign()
とスプレッド演算子 (...
) の両方を使用してオブジェクトをクローンする方法を示しています。ただし、Object.assign()
メソッドのみがセッターをトリガーします。
class Circle {
constructor(radius) {
this.radius = radius;
}
set diameter(value) {
this.radius = value / 2;
console.log('SET ', value);
}
get diameter() {
return this.radius * 2;
}
}
let circle = new Circle(100);
let cloneCircle1 = Object.assign(circle, {
diameter: 200
});
let cloneCircle2 = {
...circle
};
Code language: JavaScript (javascript)
出力
SET 200
2) 読み取り専用プロパティを持つターゲットオブジェクト
ターゲットオブジェクトに読み取り専用プロパティがある場合、Object.assign()
メソッドを使用してそのプロパティに新しい値を割り当てることはできません。ただし、スプレッド演算子 (...
) は新しいプロパティを定義できます。 color
プロパティが読み取り専用の blueSquare
というオブジェクトがあるとします。
const blueSquare = {
length: 100,
color: 'blue'
};
Object.defineProperty(blueSquare, 'color', {
value: 'blue',
enumerable: true,
writable: false
});
console.log(blueSquare);
Code language: JavaScript (javascript)
出力
{ length: 100, color: 'blue' }
Code language: CSS (css)
以下は、スプレッド演算子 (...
) を使用して style
オブジェクトと blueSquare
オブジェクトをマージする例です。
// merge style and blueSquare objects:
const style = {
color: 'green'
};
const greenSquare = {
...blueSquare,
...style
};
console.log(greenSquare);
Code language: JavaScript (javascript)
出力
{ length: 100, color: 'green' }
Code language: CSS (css)
ただし、Object.assign()
メソッドを使用すると、エラーが発生します。
// merge style and redSquare objects: ERROR
const redSquare = Object.assign(blueSquare, {
color: 'red'
});
Code language: JavaScript (javascript)
エラー
TypeError: Cannot assign to read only property 'color' of object '#<Object>'
Code language: JavaScript (javascript)
まとめ
- オブジェクトスプレッド演算子 (
...
) は、オブジェクトの独自の列挙可能なプロパティを展開します。 - オブジェクトスプレッド演算子を使用して、オブジェクトのクローンを作成したり、オブジェクトを 1 つにマージします。クローンは常に浅いコピーです。
- オブジェクトをマージする場合、スプレッド演算子は新しいプロパティを定義しますが、
Object.assign()
はそれらを割り当てます。