はじめに、の前に陳謝
要は、オブジェクトや配列の一部を変更するだけなら変数と紐づくものは変わらないし、再代入すると変わっちゃうってだけで、JSに参照渡しはないみたいです。数値でも文字列でもオブジェクトでも配列でも!
ネタ記事としてお楽しみくださいませ。
っていうか、↓この記事を読んだ方がええわ!!!
JavaScriptに参照渡し/値渡しなど存在しない
↓あとワイ自身も訂正記事を書いたからよろしくやで!
3歳娘「パパ、もう参照渡しの話はやめて?」
はじめに
値渡しと参照渡し。
この2つの言葉、プログラミングを勉強したことがある方なら聴いた事があるんじゃないでしょうか?
今回はJavaScriptにおける値渡しと参照渡しの使い分け方を調査してみました!
そのほかにも、JavaScriptの年収や新恋人についての情報も!?
記法について
文字アレルギーの方でも読みやすいように、今回は2ちゃんねる風のワイ記法を用いて解説していこうと思います!
ぶいはち君とワイ
ワイ「ぶいはち君、aっていう変数を作ってくれや。aの中身は**10
**や」
ぶいはち君「a = 10
やな。覚えとくで」
ワイ「次はbを作ってくれや。中身はaと同じや」
ぶいはち君「aと同じってことは、**10
**やな」
ぶいはち君「つまりb = 10
、覚えておくで」
ワイ「すまん、事情が変わったから、aの値は**500
**に変えてくれや」
ぶいはち君「**a = 500
**やな。分かったで」
ワイ「ちなみにbの値は何やったっけ?」
ぶいはち君「b?」
ぶいはち君「bは**10
**やで」
値渡しについて
JavaScriptでは、数値や文字列は値渡しされます。
値渡しの場合は「aの値を500
に変えてしまっても、bの値は元のまま。10
のまま」という挙動になります。
「bの値はaと同じやで」と言われても「うんうん、aと同じやな」と記憶するのではなく「b = 10
やな」と置き換えて考えてくれるのです。
ちゃんと値自体をコピーしてくれる、ということですね。
逆に、参照渡しは
「参照渡し」の場合は「bは、aと同じものを指すんやな!」と記憶するイメージです。
「bの値を聞かれたら、aと同じもんを参照して答えればええわ!」って感じです。
再び、ぶいはち君とワイ
ワイ「ぶいはち君、aっちゅう配列を作ってくれや」
ワイ「中身は1, 2, 3, 4
や」
ぶいはち君「あいよ、覚えとくで」
ワイ「bっていう配列も作ってくれや」
ワイ「中身はaと同じや」
ぶいはち君「配列bは、配列aと同じ」
ぶいはち君「覚えたで」
ワイ「事情が変わったわ」
ワイ「配列aの0番目の値を**4
**に変えてくれ」
ぶいはち君「あいよ、ほな配列aの中身は4, 2, 3, 4
やな」
ワイ「ところで、配列bの0番目の値は何やったっけ」
ぶいはち君「配列b?」
ぶいはち君「ああ、配列aと同じやつやな」
ぶいはち君「ほな、配列aを見て答えればええな」
ぶいはち君「ええと、配列bの0番目の値は**4
**や!」
参照渡しについて
JavaScriptでは、配列とオブジェクトは参照渡し1されます。
「配列bの値を聞かれたら、配列aと同じもんを参照や!」みたいなイメージです。
なので、配列aの中身をいじった後で配列bの内容を確認すると「bの内容も変わっとるやんけ!」となります。
厳密には参照先のメモリアドレスを記憶するらしいので、以下のようにイメージすると良いかもしれません。
みたび、ぶいはち君とワイ
ワイ「bという配列を作ってくれや。中身はaと同じや」
ぶいはち君「あいよ」
ぶいはち君「aという配列はどこにしまったっけな」
ぶいはち君「メモによると、3番目の引き出しやな」
ぶいはち君「bいう配列もaと同じやって言うてたな」
ぶいはち君「メモっとかんとな」
ぶいはち君「bって言われたら3番目の引き出しを参照、と」
値渡しと参照渡しの使い分け方は!?
JavaScriptでは自動的に「数値や文字列は値渡し」「配列やオブジェクトは参照渡し(っぽい値渡し)」となるので、使い分けはできないということが分かりました!
「この変数の中身を変えると、他の変数の中身も変わってまうんか?」
ということだけ意識しておけば良いと思います!
ちなみに
const array = [1, 2, 3, 4];
const arrayCopy = [].concat(array);
↑こんな感じでconcatメソッド等を使用することで、配列を値渡しっぽく丸ごとコピーできたりしますが、
シャローコピー(1段階の深さのコピー)にしかならないので、多重配列の場合は一部が参照渡しとなってしまい、正しくコピーされません。
↓こんな風に、一回JSON文字列に変換して、再パースすればええやん!などという強者もいるようです(いない)。
const json = JSON.stringify(deepNestedObject);
const objectCopy = JSON.parse(json);
「コピーガードされとるDVDでも、再生しながらビデオカメラで録画すれば複製できるで!」
みたいな感じでつよいですね!(つよい)
JavaScriptの年収は!?
JavaScriptは各種Webブラウザ上で動作するプログラミング言語ですが、なんと無料で使用することができます。
つまり、JavaScriptの年収は0円だと分かりました!
JavaScriptプログラマーの年収という意味で言うと、概ね50万円〜5,000兆円の間に収まると考えられます。
JavaScriptの新恋人は!?
JavaScriptはプログラミング言語なので、恋愛はしないと考えられます。
強いて言えば、JavaScriptの恋人はJavaScriptプログラマーある皆さんであると言えるのではないでしょうか!?
おわりに
いかがでしたか?
残念ながら今回、値渡しと参照渡しの使い分け方は見つけられませんでした!
しかし、JavaScriptの恋人は皆さんだということが分かりました!
それでは、素晴らしいJavaライフを!
〜Fin〜
ここから追記:
コメント欄でご指摘いただいた内容について書くで!
ワイ「bという配列を作ってくれや。中身はaと同じや」
ぶいはち君「あいよ」
ぶいはち君「bて言われたらaを参照やな」
ぶいはち君「完全に理解したで」
ワイ「やっぱり、aの中身は配列やなくて」
ワイ「ただの3
という数値をぶち込んどいてくれや!」
ぶいはち君「あいよ」
ワイ「ちなみにbの中身はなんやったっけ?」
ぶいはち君「さっきaの中身は変わったけど・・・」
ぶいはち君「bは配列のままや!(キリッ」
ワイ「あれ?」
ワイ「bの値を答えるときはaと同じもんを参照するんやなかったっけ・・・」
実際は「参照値」という「値」を「値渡し」していた
配列やオブジェクトの一部を変更した場合には、aにもbにもその変更が反映されますが、
値を再代入すると「その変数がどの値を参照しているか」ということ自体が上書きされてしまうため、aとbは連動しなくなってしまうのです!
いかがでしたか!?
-
実際にはC++等の参照渡しとは違い「参照値」という「値」を「値渡し」しているので「参照渡しっぽい値渡し」のようです。 ↩