0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【備忘録】分割代入とスプレッド構文、シャローコピー【TypeScript】

Posted at

分割代入とスプレッド構文、シャローコピー

TypeScript,JavaScript 初学者が関数の分割代入とスプレッド構文、シャローコピートについて勉強したのでメモを残す。

配列のプロパティ名のショートハンド

  • まずは下記の例を読んでみる
const object1 = { bar: 10, baz: 20, foo: 30 };
const object2 = { foo };
console.log(object2); //  { foo: 30 }
  • object1のキーfooobject2に代入することで、object2がキーfoo,値30のオブジェクトになる

分割代入

  • 続いて分割代入を見てみる
//  分割代入
const [num1, num2] = [10, 20];
console.log(num1, num2); //  10 20

//  オブジェクトの代入
const object = { name: "Yasushi", age: 27 };
const { name, age } = object;
console.log(name, age); //  Yasushi 27

スプレッド構文

  • 配列の中身を展開する構文で、スプレッド構文というものがある。
// 配列のスプレッド構文
> const array01 = ['A', 'B', 'C']
> array01
[ 'A', 'B', 'C' ]
> const array02 = [...array01, 'D', 'E', 'F']
> array02
[ 'A', 'B', 'C', 'D', 'E', 'F' ]

//  オブジェクトのスプレッド構文
> const object01 = { a: 1, b: 2, c: 3, d: 4 }
> const object02 = { ...object1, e: 5, f: 6, g: 7 }
> object01
{ a: 1, b: 2, c: 3, d: 4 }
> object02
{ a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7 }
  • 配列やオブジェクトの名前の前に...をつけることで中身が展開される。

マージとコピー

  • オブジェクト型の値は参照渡しのため、コピーしてもアドレスが異なるためtrueにはならない。下のコード参照。

    > const sample = { a: 1, b: 2, c: 3 }
    > const sampleCopy = Object.assign({}, sample);
    > //    sample      { a: 1, b: 2, c: 3 }
    > //    sampleCopy  { a: 1, b: 2, c: 3 }
    > sample==sampleCopy
    false
    
    • Object.assign()は第1引数がコピー先オブジェクトなのだが、割り当てた後に中身が書き変わってしまうため使うには注意が必要。コツとして第1引数にスプレッド構文を使うことでコピー元が書き変わることを防ぐことができる。

シャローコピーには注意

  • オブジェクトをコピーする際に、プロパティ値がオブジェクトだった時にオブジェクトへの参照がコピーされてしまう。そのためコピー先でそのプロパティ値を変えてしまうと、参照元のオブジェクト、つまりコピー元が書き変わってしまう。

    > const sample = {
        isSample1: true,
        isSample2: false,
        objectProperty: {
          isSample1: true,
          isSample2: false,
        }
      }
    > const sample1 = sample
    //    浅いプロパティを書き換える
    > const sample2 = {...sample, isSample1: false, isSample2: true}
    //    深いプロパティ(オブジェクト)を書き換える
    > sample2.objectProperty.isSample1 = false
    > sample2.objectProperty.isSample2 = true
    > sample2
    {
      isSample1: false,
      isSample2: true,
      objectProperty: { isSample1: false, isSample2: true }
    }
    > sample1
    {
      isSample1: true,
      isSample2: false,
      objectProperty: { isSample1: false, isSample2: true } //  シャローコピーを考慮できていないバグ(書き変わってしまった)
      }
    
    • 回避策として、一旦JSONで文字列に展開してパースする方法がある。
    > const sample2 = JSON.perse(JSON.stringify(sample1));
    > sample2.objectProperty.isSmaple1 = false
    > sample2.objectProperty.isSmaple2 = true
    > sample1
    {
      isSample1: false,
      isSample2: true,
      objectProperty: { isSample1: true, isSample2: false } //  参照していないので書き変わらない
      }
    

参考

何か指摘等ございましたら、コメントでお願いいたします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?