値渡しと参照渡しを✅

森さんのRUNTEQ卒業記事を見て、作成中のアプリに足りない要素が見えてきたので12月8日のポートフォリオレビュー会に向けて機能実装を進めようと意気込んでいる23期中野昴です。

今回は、現在ZEROKEN(作成中のアプリ名)作成中につまづいた用語である、「値渡しと参照渡し」について学習していきます

参照渡し

変数Aのデータを保存している場所を変数Bに渡すこと。双方が影響し合う。

C#Javaで用いられる用語で、javascriptで参照渡しが行われることはなく、正確には参照の値渡しという。

Vue.jsでいう双方向バインディングのこと。Aがデータを保管している場所をBに渡すため、Bのデータを変更するとAのデータも変わってしまう。

例えとして合っているか分からないが、エクセルでいう下記のようなことを指しているのかな?と思った。あでもこれだとBのデータを変えることができないから違うか。

Image from Gyazo

下記の例では、参照渡しの具体的な挙動を示している。

//参照渡し
alcohols = ["highball", "beer", "sake"]

liquors = alcohols ・・・1

liquors[0] = "wine" ・・・2

console.log(alcohols)
console.log(liquors )
> Array ["wine", "beer", "sake"]
> Array ["wine", "beer", "sake"]

alcoholsは配列を保持している。

1でalcoholsはliquorsに配列を渡している。

2でliquorsのインデックスが0の箇所をwineに上書きしている。

出力された結果の通り、2の動作によってalcoholsのデータが上書きされてしまっている。

これは、参照渡しがデータの場所を渡すことを指すからだそう。

わかりやすい例を引っ張ってきた。下記に示しておく。

「参照渡し」の場合は「bは、aと同じものを指すんやな!」と記憶するイメージです。「bの値を聞かれたら、aと同じもんを参照して答えればええわ!」って感じです。

値型と参照型

プリミティブ値でも呼び出し元変数が変わってしまうのが参照渡し。

ちなみに文献によると、

const array = [1, 2, 3, 4];
const arrayCopy = [].concat(array);

↑こんな感じでconcatメソッド等を使用することで、配列を値渡しっぽく丸ごとコピーできたりするが、シャローコピー(1段階の深さのコピー)にしかならないので、多重配列の場合は一部が参照渡しとなってしまい、正しくコピーされないみたい。

値渡し

関数に変数を(引数として)渡すときの「渡し方の種類」のひとつ。渡す変数をコピーして、コピーした変数を「これを使ってね」と渡すやり方

Vue.jsでいうところの単方向バインディング。AをBにコピーする。Bはコピーだから、Bに変更を加えてもAに影響を与える事はない。

https://qiita.com/Yametaro/items/45dbfd7f544a69ea7b36

プリミティブ値は値渡しと言われている。

//値渡し
sake_1 = "highball!"
liquor = sake
sake_1 = "nihonshu!"
console.log(sake_1)
console.log(liquor)
#output 

> "highball!!"
> "nihonshu!"

変数sake_1に"highball!"を代入した時点で変数sake_1が持っている参照が新たに作られたnihonshu!に変わるだけで、

もともと変数sake_1が持ち、変数liquorに代入された"highball!"の参照が変わるわけではないみたい。

参照渡しと値渡しの違い

まとめると、二つの違いは、呼び出し元に影響を与えるか否かで分けることができる。

値渡し:変数の中身を書き換えても呼び出し元には影響しない

参照渡し:変数の中身を書き換えると呼び出し元の変数の中身も書き変わる

https://qiita.com/Yametaro/items/21f7b1a4ae09f16f323e

https://qiita.com/yuta0801/items/f8690a6e129c594de5fb

「値渡し」と「参照渡し」の違い|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典