JS中變量有兩種數據類型值,基本類型的值和引用類型的值。基本類型就是null,undefined,Boolean,string,number,引用類型的值都是對對象的引用,即一個指向對象的指針。
引用類型為一種數據結構(其他語言中稱為類,js中之前沒有類的概念,在es6中有了(一個語法糖)),當其具體化的時候,就成為了對象,所以對象稱為引用類型的實例或值。(對象即鍵值對構成的組合。)
變量 = 標識符 + 值(保存在棧中)
1.引用類型的理解
通俗來講,引用類型就是一個模板,里面定義了初始的數據與方法,而對象就是使用這個模板構建出來的東西。
比如下面的代碼。
function creatPerson(){ var obj = new Object(); obj.name = "wangbadan"; obj.age = "18"; obj.sex = "undefined"; return obj; }
調用這個函數,就會創造出一個定義了基本的名字等信息的對象,這個函數就是一個模板。
引用類型的變量的值為指針,當你使用var obj = new Object()時,obj這個變量中的值存
儲的是什么呢?就是指向新產生的對象的指針。當使用new Object()在堆空間里面創建一個對象,obj變量的值為
保存在棧中的指針,指向堆中的對象。(js操作不能直接訪問內存空間)
這樣一來,對於函數參數是傳值就好理解了。看下面一段代碼。
1 var initObj = new Object(); 2 (function (obj){ 3 obj.name = "dashazi"; 4 })(initObj); 5 alert(initObj.name); //dashazi
傳入函數的,就是initObj的值,即指向內存中新產生的對象的指針。函數內部根據傳入的指針訪問到對象,給對象
增加了name屬性。之后輸出initObj,就會訪問相同對象,查找到name屬性,於是輸出dashazi。
2.引用類型變量的賦值
1.引用類型變量間的賦值
其實函數參數傳值是一個道理,假如a,b是兩個引用類型的變量,那么a = b,b的值就是地址,把b指向的對象的地址傳給a,對a進行操作時不涉及更換指向的操作時,就是對原本b指向的對象進行操作。(學過指針的應該能明白)
2.給引用類型賦其他值
比如a原本指向對象A,現在a=B,那么不會改變A的任何東西,只是更換了指向。同理,其他基礎類型的值也是一樣,改變指針指向的地址而已。
變量 = 標識符 + 值(保存在棧中的地址)
ps:js是一種弱類型的語言,在解析器進行解析時,會根據等式右邊的類型進行猜測需要進行使用什么樣的二進制的操作。
理解了上面的內容,結合指針的知識,從js實現原理(編譯原理)的角度看,只需按正常的邏輯推理就能知道引用類型變量的賦值機制。