標籤:class 就會 更改 define rip har 資料 null eof
JavaScript有五種基礎資料型別 (Elementary Data Type)(Undefined, null, Boolean, String, Number),還有一種複雜的資料類型,就是對象。
Undefined 其實是已聲明但沒有賦值的變數的輸出結果,null其實就是一個不存在的對象的結果
對於簡單的資料類型
它們值在佔據了記憶體中固定大小的空間,並被儲存在棧記憶體中。 當一個變數向另一個變數複製基本類型的值時,會建立這個值的副本,還有就是不能給基本類型的值添加屬性。
| 1234 |
var a = 1;var b = a;a.attr = ‘long‘;console.log(a.attr) //undefined |
上邊代碼中a就是單一資料型別(number),b就是a的副本,它們兩者都佔有不同位置,但相等的記憶體空間。
對於複雜的資料類型
複雜的資料類型即參考型別,它的值是對象,儲存在堆記憶體中,包含參考型別值的變數實際上包含的並不是對象本身,而是一個指向該對象的指標。從一個變數向另一個變數複製參考型別的值,複製的其實是指標,因此兩個變數最終都指向同一個對象。
| 12345678 |
var obj = { name: ‘long‘, age: 0};var obj2 = obj;obj2.c = 5;console.log(obj); //Oject {name: ‘long‘, age: 0, c: 5}console.log(obj2); //Oject {name: ‘long‘, age: 0, c: 5} |
我們可以看到obj賦值給obj2後,當我們更改其中一個對象的屬性值,兩個對象都發生了改變,究其原因是因為obj和obj2這兩個變數都指向同一個指標,賦值是複製了指標,所以當我們改變其中一個值,就會影響另一個變數的值。
淺拷貝
其實上邊的代碼就是淺拷貝,有時候我們只是想備份數組,但是只是簡單讓它賦給一個變數,改變其中一個,另外一個就緊跟著改變,但很多時候這不是我們想要的。
| 12345678 |
var obj = { name:‘wsscat‘, age:0 } var obj2 = obj; obj2[‘c‘] = 5; console.log(obj);//Object {name: "wsscat", age: 0, c: 5} console.log(obj2);////Object {name: "wsscat", age: 0, c: 5} |
深拷貝數組
對於數組我們可以使用slice()和concat()方法來解決上面的問題。
slice
| 12345 |
var arr = [‘ge‘, ‘yu‘, ‘long‘];var arrCopy = arr.slice(0);arrCopy[0] = ‘gai‘;console.log(arr) // [‘ge‘, ‘yu‘, ‘long‘]console.log(arrCopy) // [‘gai‘, ‘yu‘, ‘long‘] |
concat
| 1234 |
var arr = [‘ge‘, ‘yu‘, ‘long‘];var arrCopy = arr.concat();arrCopy[0] = ‘gai‘;//console跟上邊一樣 |
對象
對象我們可以定義一個新的對象並遍曆新的屬性去實現深拷貝
原始方法:
| 12345678910 |
var obj = { name: ‘geyulong‘, age: 0};var obj2 = new Object();obj2.name = obj.name;obj2.age = obj.age;obj.name = "gaiyulong";console.log(obj); // Object {name: ‘geyulong‘, age: 0}console.log(obj2); // Object {name: ‘gaiyulong‘, age: 0} |
當然我們是要封裝一個方法來實現深拷貝。
| 123456789101112 |
var deepCopy = function(source) { var result = {}; for(var key in source) { if(typeof source[key] === ‘object‘) { result[key] = deepCopy(source[key]) } else { result[key] = source[key] } } return result;}var obj2 = deepCopy(obj); |
ShareComments
JavaScript 深淺拷貝