JS的變數型別:基本型別和引用型別
基本資料型別:按值訪問,可操作儲存在變數中的實際的值。基本型別值指的是簡單的資料段。
基本資料型別有這五種:Undefined、Null、String、Number、Boolean。
引用型別:當複製儲存著物件的某個變數時,操作的是物件的引用,但在為物件新增屬性時,操作的是實際的物件。引用型別值指那些可能為多個值構成的物件。
引用型別有這幾種:object、Array、RegExp、Date、Function、特殊的基本包裝型別(String、Number、Boolean)以及單體內建物件(Global、Math)。
對於基本型別值和引用型別值的區別:
① 引用型別值可新增屬性和方法,而基本型別值則不可以。
//為引用型別值新增屬性 var p = new Object(); p.age=11; alert(p.age);//11 //為基本型別值新增屬性 var name = 'a'; name.age = 11; alert(name.age); //undefined
② 在複製變數值時,基本型別會在變數物件上建立一個新值,再複製給新變數。此後,兩個變數的任何操作都不會影響到對方;而引用型別是將儲存在變數物件的值複製一份給新變數,但是兩個變數的值都指向儲存在堆中的一個物件,也就是說,其實他們引用了同一個物件,改變其中一個變數就會影響到另一個變數。
//基本型別值 var a = 'a'; var b = a; a= 'b'; alert(b); //a
引用型別值,以陣列為例:
//引用型別值,以陣列為例 //1.對其中一個變數直接賦值不會影響到另一個變數(並未操作引用的物件) var a = [1,2,3]; var b = a; a = [1,2,3,4]; alert(a);//1,2,3,4 alert(b); //1,2,3 //2.使用push(操作了引用的物件) var a = [1,2,3]; var b = a; a.push(4); alert(a);//1,2,3,4 alert(b); //1,2,3,4
傳遞引數:按值傳遞,將函式外部的值複製給函式內部的引數(一個區域性變數),當對區域性變數進行操作時,區域性變數的變化會反應在函式外部,但是這並不會影響函式外部的值。
function add(a){ a += 10; return a; } var num = 10; var result = add(num); alert(num); //10 alert(result); //20
當然,使用物件時可能會不好理解:
function setName(obj){ obj.name = 'a'; } var p = new Object(); setName(p); alert(p.name); //a
明明引數是按值傳遞的,為什麼建立的p例項也能獲取到在setName()中新增的name屬性呢?
因為obj和p引用的是同一個物件,即便按值傳遞,obj也會按引用來訪問同一個物件。看一下下面的例子就能清楚了。
function setName(obj){ obj.name = 'a'; obj = new Object(); obj.name = 'a'; return obj; } var p = new Object(); var p2 = setName(p); alert(p.name); // a alert(p2.name); // b
在函式內部重寫obj物件,此時obj物件引用的是一個區域性物件,外部的p還是原始的引用,因此不會改變。
檢測型別:
typeof:確定變數是字串、數值、布林值還是undefined的最佳工具。
var num = 1; var a = 'a'; var b; var flag = true; var o = null; alert(typeof num); //number alert(typeof a); //string alert(typeof b); //undefined alert(typeof flag); //boolean alert(typeof o); //object
instanceof :判斷是否是某個物件型別。
var a = [1,2,3]; alert(a instanceof Object); //true alert(a instanceof Array); //true alert(a instanceof RegExp); //false