.

  好程式設計師web前端分享web測試之Js中的變數,JavaScript的變數與其他語言的變數有很大區別。JavaScript變數是鬆散型的(不強制型別)本質,決定了它只是在特定時間用於儲存特定值的一個名字而已。由於不存在定義某個變數必須要儲存何種資料型別值的規則,變數的值及其資料型別可以在指令碼的生命週期內改變。

  變數及作用域

  1.基本型別和引用型別的值

  ECMAScript變數可能包含兩種不同的資料型別的值:基本型別值和引用型別值。基本型別值指的是那些儲存在棧記憶體中的簡單資料段,即這種值完全儲存在記憶體中的一個位置。而引用型別值則是指那些儲存在堆記憶體中的物件,意思是變數中儲存的實際上只是一個指標,這個指標指向記憶體中的另一個位置,該位置儲存物件。

  將一個值賦給變數時,解析器必須確定這個值是基本型別值,還是引用型別值。基本型別值有以下幾種:Undefined、Null、Boolean、Number和String。這些型別在記憶體中分別佔有固定大小的空間,他們的值儲存在棧空間,我們通過按值來訪問的。

  PS:在某些語言中,字串以物件的形式來表示,因此被認為是引用型別。ECMAScript放棄這一傳統。

  如果賦值的是引用型別的值,則必須在堆記憶體中為這個值分配空間。由於這種值的大小不固定,因此不能把它們儲存到棧記憶體中。但記憶體地址大小的固定的,因此可以將記憶體地址儲存在棧記憶體中。這樣,當查詢引用型別的變數時,先從棧中讀取記憶體地址,然後再通過地址找到堆中的值。對於這種,我們把它叫做按引用訪問。

  2.動態屬性

  定義基本型別值和引用型別值的方式是相似的:建立一個變數併為該變數賦值。但是,當這個值儲存到變數中以後,對不同型別值可以執行的操作則大相徑庭。

  var box = new Object();

  box.name = 'zhang';

  alert(box.name);

  如果是基本型別的值新增屬性的話,就會出現問題了。

  var box = 'zhang';

  box.age = 17;

  alert(box.age);

  3.複製變數值

  在變數複製方面,基本型別和引用型別也有所不同。基本型別複製的是值本身,而引用型別複製的是地址。

  var box = 'zhang';

  var box2 = box;

  box2是雖然是box1的一個副本,但從圖示可以看出,它是完全獨立的。也就是說,兩個變數分別操作時互不影響。

  var box = new Object();

  box.name = 'zhang';

  var box2 = box;

  在引用型別中,box2其實就是box,因為他們指向的是同一個物件。如果這個物件中的name屬性被修改了,box2.name和box.name輸出的值都會被相應修改掉了。

  4.傳遞引數

  ECMAScript中所有函式的引數都是按值傳遞的,言下之意就是說,引數不會按引用傳遞,雖然變數有基本型別和引用型別之分。

  function box(num) {

  num += 10;

  return num;

  }

  var num = 50;

  var result = box(num);

  alert(result);

  alert(num);

  以上的程式碼中,傳遞的引數是一個基本型別的值。而函式裡的num是一個區域性變數,和外面的num沒有任何聯絡。

  下面給出一個引數作為引用型別的例子。

  function box(obj) {

  obj.name = 'zhang';

  }

  var p = new Object();

  box(p);

  alert(p.name);

  function box(obj) {

  obj.name = 'zhang';

  var obj = new Object();

  obj.name = 'Mr.';

  }

  最後得出結論,ECMAScript函式的引數都將是區域性變數,也就是說,沒有按引用傳遞。

  5.檢測型別

  要檢測一個變數的型別,我們可以通過typeof運算子來判別。諸如:

  var box = 'zhang';

  alert(typeof box);

  雖然typeof運算子在檢查基本資料型別的時候非常好用,但檢測引用型別的時候,它就不是那麼好用了。通常,我們並不想知道它是不是物件,而是想知道它到底是什麼型別的物件。因為陣列也是object,null也是Object等等。

  這時我們應該採用instanceof運算子來檢視。

  var box = [1,2,3];

  alert(box instanceof Array);

  var box2 = {};

  alert(box2 instanceof Object);

  var box3 = /g/;

  alert(box3 instanceof RegExp);

  var box4 = new String('zhang');

  alert(box