🧩
参照 vs スプレッド構文 vs structuredClone()
🧐 この記事は
どれがどう違うの??という話
📖 定義
前提
const original = {
name: 'John',
profile: {
age: 30
}
}
のオブジェクト original
と同じオブジェクト copy
を作りたい
以降比べる作り方をそれぞれ「参照のコピー」「スプレッド構文によるコピー」「structuredClone()によるコピー」と呼ぶ。
参照のコピー
let refCopy = original;
スプレッド構文によるコピー
let spreadCopy = {...original};
structuredClone()によるコピー
let structuredCopy = structuredClone(original);
⚖️ 参照のコピー vs スプレッド構文によるコピー
// 元のデータ
const original = {
name: 'John',
profile: {
age: 30
}
}
// 参照のコピー
let refCopy = original;
// スプレッド構文によるコピー
let spreadCopy = {...original};
// originalの値を変えてみる
original.name = 'Tom';
// 表示してみる
console.log(original.name); // Tom
console.log(refCopy.name); // Tom
console.log(spreadCopy.name); // John
というように、 refCopy
は original
の変更に引っ張られる。
spreadCopy
は元のデータが保持できている。
ちなみに、コピー側の変更も同様。
refCopyの値を変えてみる(変数定義はさっきと一緒)
// refCopyの値を変えてみる
refCopy.name = 'Tom';
// 表示してみる
console.log(original.name); // Tom
console.log(refCopy.name); // Tom
console.log(spreadCopy.name); // John
spreadCopyの値を変えてみる(変数定義はさっきと一緒)
// spreadCopyの値を変えてみる
spreadCopy.name = 'Tom';
// 表示してみる
console.log(original.name); // John
console.log(refCopy.name); // John
console.log(spreadCopy.name); // Tom
⚖️ 参照のコピー vs structuredClone()によるコピー
// 元のデータ
const original = {
name: 'John',
profile: {
age: 30
}
}
// 参照のコピー
let refCopy = original;
// structuredClone()によるコピー
let structuredCopy = structuredClone(original);
// originalの値を変えてみる
original.name = 'Tom';
// 表示してみる
console.log(original.name); // Tom
console.log(refCopy.name); // Tom
console.log(structuredCopy.name); // John
先ほどと同様、 structuredCopy
は元のデータが保持できている。
ちなみに、コピー側の変更も同様なので割愛。
⚖️ スプレッド構文によるコピー vs structuredClone()によるコピー
// 元のデータ
const original = {
name: 'John',
profile: {
age: 30
}
}
// スプレッド構文によるコピー
let spreadCopy = {...original};
// structuredClone()によるコピー
let structuredCopy = structuredClone(original);
// originalの値を変えてみる
original.name = 'Tom';
// 表示してみる
console.log(original.name); // Tom
console.log(spreadCopy.name); // John
console.log(structuredCopy.name); // John
これまでを総合するに、どっちも original
の変更には左右されない。
じゃあ何が違うのかというと
// 元のデータ
const original = {
name: 'John',
profile: {
age: 30
}
}
// スプレッド構文によるコピー
let spreadCopy = {...original};
// structuredClone()によるコピー
let structuredCopy = structuredClone(original);
// originalの値を変えてみる
original.profile.age = 20;
// 表示してみる
console.log(original.profile.age); // 20
console.log(spreadCopy.profile.age); // 20
console.log(structuredCopy.profile.age); // 30
というように、 spreadCopy
は original
内の階層2段階以上の値を変更すると引っ張られてしまう。
ちなみに、 refCopy
も変わらず original
の変更に引っ張られる。
こちらもコピー側の変更も同様。
spreadCopyの値を変えてみる(変数定義はさっきと一緒)
// spreadCopyの値を変えてみる
spreadCopy.profile.age = 20;
// 表示してみる
console.log(original.profile.age); // 20
console.log(spreadCopy.profile.age); // 20
console.log(structuredCopy.profile.age); // 30
structuredCopyの値を変えてみる(変数定義はさっきと一緒)
// structuredCopyの値を変えてみる
structuredCopy.profile.age = 20;
// 表示してみる
console.log(original.profile.age); // 30
console.log(spreadCopy.profile.age); // 30
console.log(structuredCopy.profile.age); // 20
✅ それぞれのメリットデメリット
※ いずれも上記のコードの場合
参照 | スプレッド構文 | structuredClone() | |
---|---|---|---|
文字数 ※ 右辺のみ ; 抜き |
◎ 8文字 |
⚪︎ 13文字 |
△ 25文字 |
originalを汚さない | △ | ⚪︎ 1段階まで |
◎ |
関数を含む場合 例) original.greet = function() {console.log('Hello, world!')}
|
⚪︎ originalが変更されたら変更されちゃう |
◎ originalが変更されても変更されない |
△ エラーになる |
100万回for文で回した時の時間 ※ 10回平均 |
◎ 38.98ms |
⚪︎ 253.99ms |
△ 1899.46ms |
Discussion