javascript変数のスコープ

5329 ワード

基本タイプと参照タイプ   基本タイプの値は単純なデータセグメントを意味し、参照タイプの値は複数の値からなる可能性のあるオブジェクトを意味します.   変数に値を割り当てる場合、javascript解析器はまず基本タイプか参照タイプかを決定します.基本データタイプは変数に保存されている値を直接操作してもいいです.参照データタイプの値はメモリに保存されているオブジェクトです.操作対象は実際に動作するのはオブジェクトの参照で、実際のオブジェクトの参照ではありません. 
変数の割当値が、変数の一つである上向の他の変数からコピーされます.基本データタイプの値は、変数オブジェクトに新しい値を作成し、その値を新しい変数の位置にコピーします.これはよく分かります.次の例を見てください.
var num1 = 5;

var num2 = num1;

これは基本的なデータのタイプですが、参照のタイプは?同じように元の変数の値を新しい変数にコピーします.ただし、コピーしたのは元の変数の一つのポインタです.このポインタはヒープに格納されているオブジェクトを指します.コピーが完了すると、二つの変数は同じオブジェクトを指していますので、どちらの値を変更するかは、他の変数に影響を与えます.以下のコードがあります  
var obj1 = new Object(); 

	var obj2 = obj1; 

	obj1.name = "Nicholas"; 

	alert(obj2.name);  //"Nicholas"

伝達パラメータはjavascriptの中にあります.パラメータの伝達はすべて`値の種類によって伝えられます.たとえあなたが伝わってきたのが引用タイプであっても.
function setName(obj) {     

    obj.name = "Nicholas"; 

}  

var person = new Object(); 

setName(person); 

alert(person.name);    //"Nicholas"
 
 上記のコードの戻り結果は、パラメータが参照型の伝達であるようです.最初はpersonオブジェクトに属性がないので、setNameメソッドを呼び出した後、パラメータobjにnameパラメータを追加し、外のpersonプリントperson.nameに値があるということは、明らかに引用伝達の効果です.しかし、このような現象に惑わされないでください.javascriptは引用タイプのパラメータを伝える時、このパラメータが変わらない限り、やはり引用タイプによって処理します.しかし、変更効果があるだけでは全然違います.  
function setName(obj) {     

    obj.name = "Nicholas";     

    obj = new Object();     

    obj.name = "Greg"; 

}  

var person = new Object(); 

setName(person); 

alert(person.name);    //"Nicholas" 
 
上記の例では違いが見られますが、もし本当に引用伝達ならば、Objは新たに値を賦与し、さらにnameパラメータを加えて、最後のpersonはGregの名前をプリントしたはずですが、結果は元の値です.javascriptはここで大きな穴を掘ったということだけが説明できます.   実行環境とスコープ実行環境(execution context)は、関数または変数にアクセスできる他のデータを定義し、それぞれの行動を決定しました.各実行環境には、関連する変数オブジェクトがあります.環境で定義されている変数と関数はすべてこのオブジェクトに保存されます.   グローバル実行環境は最も周辺の実行環境であり、ウェブブラウザではwindowオブジェクトであるため、すべてのグローバル変数と関数はwindowの属性と方法として作成され、ある実行環境のすべてのコードが実行された後、この環境は破壊され、その中に保存されている変数と関数の定義も廃棄されます.(グローバル実行環境はアプリケーションが終了するまで、ブラウザが閉じているときに破壊されます.)  __各関数には自分の実行環境があります.プログラムが一つの関数に実行されると、関数の環境が作成され、現在のプログラムの流れに入ります.関数の実行が完了したら、プログラムフローはそれをポップアップして廃棄します.コントロールを一つの環境で実行すると、変数のオブジェクトの範囲チェーンが作成されます.意味は、異なる階層の実行環境において、各実行環境における変数の秩序あるアクセスを保証し、次のコードを見てください.
var color = "blue";  

function changeColor(){     

    var anotherColor = "red";  

    function swapColors(){         

        var tempColor = anotherColor;         

        anotherColor = color;         

        color = tempColor; 

        //  swapColors        tempColor,anotherColor color          

    } 

    //       anotherColor color,     tempColor 

    swapColors(); 

}  
 
列子と図を通して、内部環境は、その上のすべての外部環境に作用するドメインチェーンを介してアクセスできるが、外部環境は内部環境内のいかなる変数と関数にもアクセスできないことが分かる.これらの環境は線形で、順序がある.       各環境は、変数と関数名を照会するために作用するドメインチェーンを上に検索することができますが、どの環境も、作用するドメインチェーンを下に検索することによって他の実行環境に入ることはできません.  上記の話はとても重要です.次の例を見てみます.
var color = "blue";  

function getColor(){     

    return color; 

}  

alert(getColor());  //"blue" 
 
get Color関数の中のカラー変数は、内部から上位外部環境を検索するカラーであることは明らかである.   検索中に同名のローカル変数が現れたら、この検索は停止されます.
var color = "blue";  

function getColor(){     

    var color = "red";     

    return color; 

}  

alert(getColor());  //"red"