認識JavaScript中的變數 JavaScript中的變數有兩種類型,一種是基本類型、一種是引用類型。 + 基本數據類型:Defined,Null,Boolean,Number,String。註意String是屬於基本數據類型,這不同於其他高級語言。 + 引用類型即對象,包括內置對象和自定義對象 ...
認識JavaScript中的變數
JavaScript中的變數有兩種類型,一種是基本類型、一種是引用類型。
- 基本數據類型:Defined,Null,Boolean,Number,String。註意String是屬於基本數據類型,這不同於其他高級語言。
- 引用類型即對象,包括內置對象和自定義對象。
需理解的差異
關於複製
對於基本類型的變數,就是我們印象中對於變數的理解。
var a = "TabWeng";
var b = a;
console.log("a:"+a+", b:"+b);
a = "Weng";
console.log("a:"+a+", b:"+b);
運行結果:
a:TabWeng, b:TabWeng
a:Weng, b:TabWeng
我們來看另一個例子:
var a = new Object();
a.name = "TabWeng";
var b = a;
console.log("a'name:"+a.name+", b'name:"+b.name);
a.name = "Weng";
console.log("a'name:"+a.name+", b'name:"+b.name);
運行結果:
a'name:TabWeng, b'name:TabWeng
a'name:Weng, b'name:Weng
這個結果就不同了,我只修改了 a.name 的值,b.name 的值也跟著發生變化,答案只能是它們的值都指向同一個地方,即它們都指向同一塊記憶體,只要記憶體的值發生變化,因為另一個也指向這個記憶體,自然就獲取了變化後的值。而對於基本類型的變數,也就是我們大家所理解的,在複製後就開闢新的記憶體進行數據存儲,所以兩個變數互不幹擾。
關於傳參
JavaScript的參數傳遞都是按值傳遞
基本類型變數很好理解,但是對於引用類型的變數也許存在疑惑,不要緊,你只要理解下麵這句話即可:
引用類型變數的傳參是按值傳遞,但是訪問引用變數的值時依然是按引用訪問同一個對象。
下麵舉三個例子,對於引用類型,讀者需理解透徹。
第一個例子是基本類型變數的傳參,第二、三是引用類型變數的傳參:
var name = "TabWeng";
function sayFunction(name){
name = "Hi,"+name;
console.log(name);
}
sayFunction(name);
console.log(name);
運行結果:
Hi,TabWeng
TabWeng
var Person = new Object();
Person.name = "TabWeng";
function sayFunction(obj){
obj.name = "Hi," + obj.name;
console.log(obj.name);
}
sayFunction(Person);
console.log(Person.name);
運行結果:
Hi,TabWeng
Hi,TabWeng
雖然是按值傳遞,但是在訪問的時候是按引用訪問同一個對象,所以Person.name也改變了。
var Person = new Object();
Person.name = "TabWeng";
function sayFunction(obj){
obj.name = "Hi," + obj.name;
console.log(obj.name);
obj = new Object();
obj.name = "My name is Tom, I am go to another memory";
console.log(obj.name);
}
sayFunction(Person);
console.log(Person.name);
運行結果:
Hi,TabWeng
My name is Tom, I am go to another memory
Hi,TabWeng
這個例子說明瞭不是按引用傳遞,否則第三行的結果應該是My name is Tom, I am go to another memory。
作用域
作用域鏈
作用域鏈很好理解,一句話概括變數在作用域中的訪問許可權:
外面不能訪問裡面,裡面可以訪問外面,在搜索變數時,從裡向外搜索。
作用域鏈是在創建函數的時候產生的,在創建函數的時候,會創建它的執行環境和作用域鏈,一開始的時候,會創建一個包含全局環境(全局對象)的作用域鏈,然後把該函數的活動對象推入到作用域鏈的前端(也就是裡面,最下麵),如果函數裡面還有函數,那麼再依次推入,這樣就形成一條作用域鏈。
假設作用域鏈(實際上是一張列表)裡面有三個指針指向三個對象,列表最上面的指針指向全局對象(假設稱為obj_1),中間的指針指向活動對象(假設稱為obj_2),下麵的指針指向最前端的活動對象(假設稱為obj_3)。那麼,當前的活動對象的變數是無法訪問下麵指針的活動對象的,即obj_2無法訪問obj_3的變數,反之就可以。
延長作用域鏈
- try catch
- with
以上兩者可延長作用域鏈,把變數放在作用域前端(即當前環境)。
沒有塊級作用域
for(var i = 0; i < 3; i++){
console.log("in i: "+i);
}
console.log("out i:"+i);
運行結果:
in i: 0
in i: 1
in i: 2
out i:3
這與其他高級不同。
參考
- 《JavaScript高級程式設計》