変数
基本型変数と参照型変数がある
具体的に言うと、基本型変数はその値そのものの情報を別の変数に渡していて、参照型変数ではメモリ上の参照している情報を別の変数に渡している。
- 基本型変数:let x = 1 => データ型(値)を格納。コピー品。
- 参照型変数:let x = {x:1, y:2} => オブジェクトを格納。参照先をコピーしている。監視する人がもうひとり増えるイメージ。
参照とは、アドレス(住所)を見に行く大家のイメージ。マンションや家の住人が変わっても、見に行く住所は変わらない。
値渡しと参照渡しの例
//1.基本型変数
const a = 123;
let b = a;//値そのものを右辺から左辺へコピー
b++;
console.log(b);//124
console.log(a);//123
//参照型変数(オブジェクト)
//2.参照先が同じ
let a = {x:1, y:2};
let b = a;//参照をコピーしている
b.x++;
console.log(b.x); //2
console.log(a.x); //2
//3.参照先が変わるとき
let a = {x:1, y:2};//
let b = a;
a = {x:2, y:2};
console.log(b.x); //1
console.log(a.x); //2
基本型のとき、値そのものがコピーされるので
コピー品が変わってもオリジナルは変わらない。参照型のとき、参照元(住所)がコピーされる。大家が2人になり、同じアドレス(住所)を見ているイメージ。どちらの大家も住所の住人を変更できる。
参照先が変われば、見ている住所が変わる。一人の大家がマンションの売却し、別のマンションを購入したイメージ。マンションの住人を変えても、どちらにも関係ない。
関数の値渡しついて
関数の値渡しとは、関数呼び出し式で、引数という形で、関数に値を渡すこと。
この渡し方も、値渡しと参照渡しがある。
基本型のとき
function(a, b) {
return a / b;
}
f(5, 4); //引数を関数内に渡している
//1.25
関数の引数のスコープを考える
引数に値を渡したとき、思った挙動にならない時がある。
たとえば、変数に10を足す関数を作ったとする
//引数に渡された値に10を足す関数
function myFunc1(n) {
n = n + 10;
}
var num = 10;
myFunc1(num);
console.log(num); //10
期待値的には12を返してほしいところだが、10を返す。
関数の引数はローカルスコープになるからだ。
引数nは関数内では有効になるが、グローバル変数には影響を与えない。
そのため、console.log(num)のnumはグローバル変数のnumを参照するため、値は10となる。
参照型のとき
また渡される値がオブジェクトの場合はどうだろうか。
パターンとしては2パターンある。
function changeArr(arr) {
arr = new Array(1, 1, 1);
}
var theArr = [1, 3, 5];
changeArr(theArr);
console.log(theArr); //1, 3, 5
これは、先ほどと同じ、ローカルスコープが効いているので関係はない。
しかし、変数の内部の値を変更するようなメソッドを実行したり、あるいはプロパティを変更すると、呼び出しもとの変数に変更が反映される。
function changeArr(arr) {
arr.push(9);
}
var numArr = [1, 3, 5];
changeArr(numArr);
console.log(numArr); //1, 3, 5, 9
引数arrの参照先と変数numArrの参照先が同じになる。
このとき、同じ住所をみているので、引数arrでメソッドを使い加えた変更は
numArrでも同じように見ることができる。
オブジェクトについて
const obj = {x:1 , y:3};
objのことをオブジェクトobjを呼ぶとき
「オブジェクトobj」は「変数objから参照されるオブジェクト」である。
obj自身がオブジェクトなのではなく、objが消滅してもオブジェクト自身は存在することができる。