1. 程式人生 > >JavaScript學習筆記(一)——變數、作用域問題

JavaScript學習筆記(一)——變數、作用域問題

一、基本型別和引用型別的值

ECMAScript變數包含兩種不同資料型別的值:基本型別值和引用型別值。

基本型別值指儲存在棧記憶體中的簡單資料段,即完全儲存在內容中的一個位置。

引用型別值則指儲存在堆記憶體中的物件,實際上儲存的是一個指標,指向記憶體的另一個位置,該位置儲存物件。

1.動態屬性

對於引用型別的值,可以為其新增屬性與方法,例如

var person=new Object();
person.name="Tom"
alert(person,name);

 但是對於基本資料型別的值則無法新增屬性。

2.複製變數值

如果從一個變數向另一個變數複製基礎型別值的時候,會在棧中建立一個新值,這兩個值之間相互獨立,互不影響。

var num1=5;
var num2=num1;
num2=7
alert(num1)  //輸出5
alert(num2)  //輸出7

 如果複製的是引用型別的時候,會在棧中建立一個指標,此時兩個指標指向同一物件。當修改物件的屬性值時,無論呼叫的是哪一個指標,傳出來的值都是一致的,因為指向的是同一空間裡的內容,除非指標指向改變。

var obj1=new Object();
var obj2=obj1;
obj1.name="Tom"
alert(obj2.name);   //輸出Tom

注意:函式的引數在進行傳遞的時候,與這個原理相同。

二、執行環境和作用域

執行環境(execution context)定義了變數或函式有權訪問的其他資料,每個執行環境都有一個與之關聯的變數物件,環境中定義的變數和函式都儲存在這個物件中。

在Web瀏覽器中,全域性執行環境被認為是window物件,因此所有的全域性變數和函式都是作為window物件的屬性和方法建立的。當執行環境的所有程式碼執行完畢後,該環境也隨之銷燬(全域性執行環境直到應用程式退出——例如關閉瀏覽器時才銷燬)。

當我們的程式碼在環境中執行的時候,都會形成一條作用域鏈,以保證變數與函式的有序訪問。

var color="blue";
function changeColor(){
    var anotherColor = "red";
    function swapColor(){
        var temp=anotherColor;
        anotherColor=color;
        color=temp;
    }
    swapColor();
}
changeColor();
alert(color)   //輸出red

每個環境都可以向上搜尋作用域鏈,以查詢變數名與函式,但任何環境不得向下搜尋作用域鏈而進入另一個執行環境。

注意:(1)使用try-catch中的catch塊、with語句,這兩種方法可以延長作用域。

           (2)JavaScript沒有塊級作用域,即if、for語句中定義的變數,依舊會存在與外層的執行環境中。

1.宣告變數

變數在未經宣告的情況下初始化,那麼變數會被自動新增到全域性環境中。

function add(num1,num2){
    var sum=num1+num2;
    return sum;
}
var result=add(5,10);
alert(sum)  //出錯,sum不是有效變數

此時在全域性環境中是無法訪問到add函式中的sum變數的。

function add(num1,num2){
    sum=num1+num2;
    return sum;
}
var result=add(5,10);
alert(sum)  //30

執行完add函式後,由於sum是在全域性環境中,因此可以繼續進行訪問。

2.查詢識別符號

在某個環境中為了查詢一個識別符號,會在作用域鏈的最前端進行查詢,如果再區域性查詢到,則搜尋停止,否則直到全域性環境中。

var color="red"
function find(){
    return color;
}
alert(find());  //red

首先在區域性中搜索color,區域性中不存在則向上進行搜尋,在全域性環境中找到color的識別符號,則停止。

var color="red"
function find(){
    var color="blue"
    return color;
}
alert(find());  //blue

在這個搜尋過程中,已經在區域性裡發現了color識別符號,則無須到全域性環境中查詢。