針對於JavaScript的對象和數組(數組也是對象)淺拷貝只是引用,內存不變;而深拷貝就是遞歸賦值。
深拷貝是不一樣內存,相互獨立。而淺拷貝會影響程序員
//1.循環複製數組 var arr = [1,2,3],arr2 = []; for(var i=0;i<arr.length;i++) { arr2[i] = arr[i]; } //2.還能夠用一句簡單的代碼實現上面的深拷貝: Array.prototype.push.apply(arr2,arr); //3.先把這個對象轉化爲字符串,在拷貝,再轉化回來便可 JSON.parse(JSON.stringify(obj))
別急着走,利用window.JSON的方法作深拷貝存在2個 缺點:數組
例以下面這種狀況:對象裏包含函數數據結構
var o1 = { name:"小明", age:12, city:"廣州", schools:["小學","中學","大學"], say:function(){ alert(this.name); } }
for...in 遍歷對象,找出自身的屬性,且會搜索原型,即也會查找原型上的屬性
__proto__不可枚舉的屬性app
obj.hasOwnProperty() 返回布爾值 判斷屬性是不是自有屬性函數
JSON.parse(JSON.stringify(o1)) 能夠將只有屬性/不存在方法的對象複製
JSON.stringify 將對象轉換成字符串,轉換的過程,會忽略掉方法.this
//下面的方法能夠實現 深深度複製(複製包括函數)spa
function deepClone(oldObj){ var newObj = {}; for(var key in oldObj){ if(oldObj.hasOwnProperty(key)){ if(oldObj[key].constructor == Array){ //判斷oldObj[key]值是否數組/對象 newObj[key] = oldObj[key].slice(); }else if(oldObj[key].constructor == Object){ newObj[key] == deepClone(oldObj[key]); }else{ newObj[key] = oldObj[key]; } } } return newObj; } var o2 = deepClone(o1);
固然,你明確知道他們的缺點後,若是他的缺點對你的業務需求沒有影響,就能夠放心使用了,一行原生代碼就搞定。
目前我在開發業務場景中,大多還真能夠忽略上面2個缺點。每每須要深拷貝的對象裏沒有函數,也不須要拷貝它原型鏈上的屬性。操作系統
因爲js中的對象都是複雜數據類型,這種數據在內存中存儲的時候,存放在堆中。當簡單賦值的時候,實際上是將該對象的指針指向同一個堆地址。
簡單的數據類型存放在棧中,當對簡單的數據類型進行賦值的時候,其實就是直接在棧中新開闢一個地方專門存儲同樣的值。prototype
數據結構裏的堆棧:
棧(stack): 由編譯器自動分配, 存放函數的參數值, 局部變量的值等. 其操做方式相似於數據結構中的棧.
堆(heap): 通常由程序員分配釋放, 若程序員不釋放, 程序結束時可能由OS回收. 這裏OS是指: 操做系統(Operating System)指針