JavaScript

JavaScriptの参照に注意【オブジェクト型の特有な動き】

どうも、つよぽんです!

今回は、JavaScriptの参照の動きについて解説します。

今回の記事は次のような方に向けて書きました。

想定読者
  • 参照って何?
  • 変数に値を代入するときにプリミティブ型の値とオブジェクト型の値でどんな違いがあるか知りたい

この記事では「オブジェクト型の参照の概念」ついて解説していくので、この記事を読み終わる頃には次のことがわかるようになります。

この記事を読み終えた後のあなた
  • 参照とはどういうものか理解するようになる
  • オブジェクト型の値を関数の引数として渡したり、別の変数に代入するときに何をすればよいかわかるようになる

今回の記事は以下の学習コンテンツのスライドを詳しく解説した記事となります。以下の記事と合わせて読むことでより理解度を深めていただけるかと思います。

あわせて読みたい
JavaScriptの配列で参照を理解する【オブジェクト型の動き】今回はJavaScriptの参照の学習をします。プリミティブ型とオブジェクト型で変数に値を代入するときの動きは異なります。プリミティブ型は値そのものが代入され、オブジェクト型は「参照」が代入されます。参照が何か理解して参照を使いこなせるようになりましょう。...

それでは次の内容で話を進めていきます。

今回の内容
  1. JavaScriptの参照とは
  2. JavaScriptの参照を変数に代入するときの注意点

JavaScriptの参照とは

この章では、「JavaScriptの参照とは何か?」について解説していきます。

参照とは、一言で言うと「オブジェクト型の値が保存されているエリア」のことです。

言葉だけではイメージが付きづらいと思うので、プリミティブ型の値が変数に保存される場合と、オブジェクト型の値が変数に保存される場合で画像を使って比較していきます。

プリミティブ型の値を変数に保存する場合

以下の画像は「プリミティブ型の値を変数に代入したときのイメージ」になります。

プリミティブ型の値が変数に保存されている時のイメージプリミティブ型の値が変数に保存されている時のイメージ

画像の説明に書いている通り、値がそのまま変数に直接格納されるイメージとなります。

上の画像で使っている値を例にして、「const number2 = number;」のように「変数number」に保存されている値を新しく「変数number2」に代入した場合、「変数number2」には直接10が格納されます。

オブジェクト型の値を変数に保存する場合

以下の画像は「オブジェクト型の値を変数に代入したときのイメージ」になります。

オブジェクト型の値が変数に保存されている時のイメージオブジェクト型の値が変数に保存されている時のイメージ

画像の説明に書いている通り、変数にはオブジェクト型の値が直接保存されるわけではなく、「参照」という形式で間接的にオブジェクト型の値にアクセスします。

そして、この時オブジェクト型の値、つまり参照を保存している変数を別の変数に代入したときは、同じ参照を共有することになります。

以下の画像は同じ参照を共有しているイメージをあらわしたものです。

参照を保持する変数を別に変数に代入したときのイメージ(参照の共有)参照を保持する変数を別に変数に代入したときのイメージ(参照の共有)

上の画像では「変数numberList1」「変数numberList2」には同じ参照情報が保存されています。

この参照情報の先、つまり上の画像だと「参照A」が、この章の始めの方で話した「オブジェクト型の値が保存されているエリア」ということになります。

JavaScriptの参照を変数に代入するときの注意点

この章では、「参照を変数に代入するときの注意点」について解説します。

ここで話す注意点を一言でまとめると、「参照先の値を別の変数に代入したいときは参照のコピーを渡す」ということです。

参照をそのまま渡した場合」「参照のコピーを渡した場合」でどんな違いがあるのか、それぞれ説明していきます。

参照の値を変更すると、同じ参照を持つ他の変数の値も一緒に変更される

この項目では「参照をそのまま渡した場合」について解説します。

以下の画像は「const numberList2 = numberList1」のように、同じ参照先をそのまま別の変数に渡したときの様子を表したものです。

同じ参照を持つ全ての変数に影響を与える同じ参照を持つ全ての変数に影響を与える

このとき、参照先の値を更新すると、同じ参照先を保持している変数の値は全て同時に変更されてしまいます。

以下のサンプルコードは「numberList1.push(4)」で「numberList1」に対して値を更新したコードですが、「numberList2」にも「numberList1.push(4)」の影響で4が追加されています。

他の変数にも影響を与えていることを表している様子他の変数にも影響を与えていることを表している様子

この挙動がオブジェクト型の値を取り扱うときに注意しなければいけない点です。

この問題を防ぐためには、次の項目で紹介する「参照先のコピーを渡す」ということをすれば解決します。

上の画像内のサンプルコードは以下のリンク先から直接確認できます。

配列を使った参照のサンプル1

参照を共有しないで、参照内の値のコピーを渡すことで別の変数に影響を与えないようにする

この項目では「参照のコピーを渡した場合」について解説します。

以下の画像では「const numberList2 = numberList1.slice()」で、参照先のコピーを「numberList2」に渡したことを説明しています。

参照先のコピーを渡して、それぞれ独立した参照を持つ変数にする参照先のコピーを渡して、それぞれ独立した参照を持つ変数にする

Array.prototype.slice()」を使うと配列のコピーを作ること出来ます。

参照先のコピーを渡したことにより、「numberList1」は「参照A」を持ち、「numberList2」は「参照B」を持ち、それぞれ異なる参照先を見ることになります。

そのため、「numberList1.push(4)」とnumberList1の値を更新しても、別の参照を持つnumberList2は全く影響を受けずに済みます。(以下の画像で説明)

参照Aを更新しても参照Bには影響はない参照Aを更新しても参照Bには影響はない

以下のサンプルコードでは「numberList1.push(4)」で「numberList1」に対して値を更新しても、「numberList2」には影響を出ていないことがわかります。

参照先が違っていれば他の変数には影響がないことを表したサンプルコード参照先が違っていれば他の変数には影響がないことを表したサンプルコード

このように、参照先の値をコピーすればいつのまにか変数に保存している値が書き換わったという意図しない挙動を未然に防ぐことが出来ます。

上の画像内のサンプルコードは以下のリンク先から直接確認できます。

配列を使った参照のサンプル2

まとめ

今回の話をまとめると次のとおりです。

今回のまとめ
  • オブジェクト型が変数に代入されるときは「参照」が保存される
  • 同じ参照先を持つ変数は互いに影響を与え合うので注意が必要
  • オブジェクト型の意図しない上書きを防ぐためには「参照先のコピー」を別の変数に渡せば良い

今回の内容は以下の記事内のスライドの補足資料として作成しました。スライドの全部を確認したい方は以下の記事も参照して頂けたらと思います。

あわせて読みたい
JavaScriptの配列で参照を理解する【オブジェクト型の動き】今回はJavaScriptの参照の学習をします。プリミティブ型とオブジェクト型で変数に値を代入するときの動きは異なります。プリミティブ型は値そのものが代入され、オブジェクト型は「参照」が代入されます。参照が何か理解して参照を使いこなせるようになりましょう。...
【やる気満々な方向け】学習サポートとオンライン講義やってます!

Webエンジニアになりたい人向けに、MENTA にて『【やる気満々な方向け】未経験からのWebエンジニア育成コース』というプランを用意しております。

このプランでは、主に「【学習コンテンツ】Web開発」を使って学習を進めていただきます。

あわせて読みたい
Web開発Webエンジニアになるために必要な知識・スキルを学習できるコンテンツを用意しました。未経験者でも、①開発環境の準備、②Webの基本的な仕組み、③HTML、④CSS、⑤JavaScriptと順を追って学習することでスキルが身につくことを目的に教材を作成しています。...

誰向けのプラン?

こちらのプランは次のような方に向けて作られています。

プラン対象者
  1. Progateやドットインストールで一通り学習したけど、次に何をすればよいかわからない
  2. Webエンジニアになるまでの学習プランがあると助かる
  3. 学習していてわからないところが出てきたときに質問したい
  4. コードレビューして欲しい
  5. オンライン講義に参加したい
  6. 学習した内容をアウトプットした際に、フィードバックがもらえたら嬉しい
  7. おすすめの学習教材を知りたい
  8. Webフロントエンド・バックエンドを学習したい
  9. フルスタックエンジニアになりたい
  10. 文系出身で今までプログラミングをしてこなかったけど、将来Webエンジニアになりたい
  11. 将来フリーランスになることを目指している

プラン内容は?

【やる気満々な方向け】未経験からのWebエンジニア育成コース』では次のことを行っております。

プラン内容
  1. Web白熱教室の学習コンテンツをメインに、指定した教材を使って学習する (学習プランに沿って学習を進めていただきます。)
  2. 学習コンテンツの課題をこなしたあとは、僕にコードレビュー依頼を投げていただくことで、コードを添削する(課題クリア後は、引き続き学習プランの内容を続けていただきます。)
  3. プラン契約者が参加するSlackグループにて質問し放題
  4. Slack内にある「アウトプットの場」チャンネルにて、学習したことをアウトプットをしていただくことで、それに対しフィードバックをする (学習内容のアウトプットは復習にもなるため、アウトプットすることを強く推奨します。)
  5. 画面共有を使ったオンライン講義 (オンライン講義は録画して、いつでもふり返れるようにしています。(オンライン講義動画(ウェビナー動画)))
  6. 学習プラン以外の内容に対しての質疑応答 (内容によっては回答できないものもありますが、まずは気軽に質問していただけたらと思います。)
  7. 不定期で行うオフラインでの勉強会に参加(僕自身が東京住みのため、東京・もしくは東京近郊で開催します)

1日1回カフェでコーヒー1杯頼むくらいの金額で参加できます

1日1回、カフェでコーヒー1杯分くらいの値段(約330円)」で以下の環境が手に入るとイメージして頂けたらと思います。

  1. コードを添削してもらえる
  2. 学習したことのアウトプットに対してフィードバックしてもらえる
  3. いつでも質問出来る
  4. 週1のオンライン講義に参加できる
  5. 過去のオンライン講義動画を好きな時間に復習できる(いつでも閲覧可能)
  6. 不定期で行うオフラインでの勉強会に参加できる(僕自身が東京住みのため、東京・もしくは東京近郊で開催します)
  7. 自分の住まいの近場のメンティーさん同士で集まって、オフラインで勉強会を開くのも可能(初めて開催する場合は事前に僕に連絡をいただけたらと思います)

学習教材には、このサイトで用意している「【学習コンテンツ】Web開発」を使います。

【学習コンテンツ】Web開発」を使って学習を進めることで、Webのフロントエンドとバックエンドのスキルを身につけていくことができます。

プログラミングスクールとの比較

プログラミングスクールに通う場合は1ヶ月で10万円以上するところも多いですし、3ヶ月で50万円、更には100万円するところもあります。

プログラミングスクールの値段が高い理由は、「プログラミングスクールで働いている人の人件費」「就職のサポート」なども含まれているからです。

10万円50万円100万円」のいずれの場合も、自己投資とはいえ、支払うのにはだいぶ勇気がいる金額かと思います。

オススメの学習方法

個人的にオススメするのは、プログラミングのできるメンター(師匠)を見つけて、まずは1ヶ月プログラミング学習をしてみて、自分にプログラミングが向いているかどうか確かめてみることです。

10万円50万円100万円」を払って、学習していく中で「やっぱり自分にはプログラミングは向いてない」と判断した場合、その金額はかなりの痛手となります。

そのため、まずは「これくらいの金額なら最悪失っても痛くないな」の値段で教えてくれるメンターを見つけて、そのメンターに色々と質問をしてみましょう。

それで、「良さそうだな」と思ったら教えてもらうといった流れで学習を始めると、金額もだいぶ節約できます。

注意点

ただし、参加者が増えてきたら、1人1人へのサポートの質を維持するのが難しくなるので、値上げする可能性もあります。

値上げする理由は次の以下の理由となります。

  • 値段を上げて参加ハードルをあげることで、自己解決スキルも身につけたいと考えている学習意欲の高い人だけが参加するようになる
    • 調べたらすぐにわかることを、自分で調べずに何でもかんでも質問すると、自己解決スキルも身につかない
    • 更に、他のメンティーさんの対応する時間が取れなくなりサポートの質の低下にも繋がる

詳しく話を聞いてみたい方は

以下のいずれかでメッセージをいただけたらと思います^^

 

プラン内容については以下のリンク先からも確認することが出来ます^^

【やる気満々な方向け】未経験からのWebエンジニア育成コース

COMMENT

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です