JavaScriptの変数タイプとパラメータ転送

2521 ワード

1.変数の種類
JavaScriptには、基本タイプの値と参照タイプの値の2つの異なるデータタイプの値が含まれています.
基本タイプの値は5種類しかありません.undefined、Null、Boolean、Number、Stringです.参照の種類はオブジェクトと考えられます.
基本タイプと引用タイプはどう違いますか?あまり変わらないように見えます.これらの違いは、基本的なタイプの値が値でアクセスされ、参照タイプの値が参照でアクセスされることです.値でアクセスするとメモリに保存されている実際の値を直接操作できますが、参照でアクセスすると、オブジェクトに属性を追加する以外は、オブジェクトの参照だけが操作されます.
もう一つ大きな違いは、引用タイプの値は属性と方法を追加できますが、基本タイプの値はだめです.
var phone = new Object();
phone.brand = 'Apple';
console.log(phone.brand) //"Apple"
上記のコードはオブジェクトを新規作成し、phone変数に保存しました.そして私たちはこのオブジェクトにbrand属性を追加し、このオブジェクトにApple'を割り当てました.
しかし、基本タイプの値に属性を追加することはできません.基本タイプの値に対して上記のコードの動作を実行しても、エラーは発生しません.
var book = 'Software Engineer';
book.page = 100;
console.log(book.page); //undefined
上のコードは1つの文字列をbookオブジェクトに割り当て、bookのためにpage属性を追加しましたが、出力時はundefinedです.基本タイプの値は属性を追加できません.
上記の2つの違い以外にも、基本タイプの値と引用タイプの値はコピー時にも差があります.
var a = 1;
var b = a;
console.log(a);  //1
console.log(b);  //1
console.log(++a);   //2
console.log(b); //1
上記のコードからは、基本的なタイプの値がコピーされたときに、コピーされた変数の値のコピーをそのままコピー変数に割り当てたという結論が得られます.言い換えれば、コピー変数とコピーされた変数は完全に独立しており、いずれの動作も他のものに影響を与えない.
ただし、変数の値が参照タイプの値であると、状況は全く違ってきます.
var a = new Object();
var b = a;
a.name = 'JavaScript';
console.log(a.name);    //JavaScript
console.log(b.name);    //JavaScript
console.log(a == b);    //true
a変数は参照タイプ値(オブジェクト)を保存し、aをbに割り当てます.a変数にname属性を追加したら、a、b変数に同じ属性(name)と同じ属性値(JavaScript)が現れていることが分かります.ここで結論が出そうとしているのを見て、次の行のコードは私達の予想を直接確認しました.――aとbの値は同じです.
JavaScriptには指針がないにもかかわらず、私たちは依然として指針の概念を使ってこの現象を理解することができます.実際にはaとbは同じポインタを持っています.このポインタは新しいオブジェクトを指します.ですから、aを操作してもbを操作しても、実際に操作するのは同じ対象です.
2.パラメータ転送
JavaScriptではすべての関数のパラメータが値によって伝達されます.つまり、上記の基本タイプの値のコピーと同じです.
function foo(num){
    return num++;
}
var a = 1;
console.log(foo(a));    //2
console.log(a);     //1
伝達されるパラメータが基本的なタイプの値であれば、基本的なタイプの値のコピーと同じように、パラメータnumが付与されるのはaのレプリカであり、つまり変数aとパラメータnumは完全に独立しており、換言すれば関数内のnumに対するいかなる変化もaに影響しない.
ただし、伝達パラメータが参照タイプの値であれば、状況は違ってきます.
function foo(obj){
    obj.name = 'JavaScript';
}

var b = new Object();
foo(b);
console.log(b.name);    //JavaScript
上記の運転結果は、伝達するパラメータが基本タイプの値である場合とは違って、最初に言った「すべての関数のパラメータは値で伝達されている」ということと矛盾しているようです.
実際には、以前のように指針を使って参照の種類の値を理解すれば、この状況を説明できます.「値による伝達」は間違っていません.私たちが伝達するのはb変数が保存しているオブジェクトではなく、b変数がそのオブジェクトのポインタ(b変数が保存されているのはオブジェクトのポインタ)を指しているからです.つまり、パラメータobjと変数bの値はいずれもオブジェクトポインタであるため、自然にパラメータobjの修正がb変数に影響を及ぼします.