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識別符號,則無須到全域性環境中查詢。