三種方法的形式存在必定的相似,可是也存在各個之間不相同的地方。javascript
淺拷貝和深拷貝是用在對象(Object)或者數組(Array)這樣的數據類型拷貝賦值時候的說法,而賦值操做也能夠用在基礎的數據類型,如Number、String等;java
var aa = [ 1, 2, 3 ],bb; bb = aa; console.log(aa, bb); // aa = [1,2,3], bb = [1,2,3]; bb.push(5);//這裏操做的是aa、bb指向的存儲空間,因此aa、bb的值都發生了變化 console.log(aa, bb); // aa = [1,2,3,5], bb = [1,2,3,5]; bb[0] = 10;//這裏操做的是aa、bb指向的存儲空間,因此aa也發生了變化 console.log(aa, bb); // aa = [10,2,3,5], bb = [10,2,3,5]; bb = [ 2, 3, 4 ];//這裏已經把bb指向了另外一個數組,因此不會影響aa的值 console.log(aa, bb); // aa = [1,2,3,5], bb = [2,3,4];
ps:該淺拷貝的方法會覆蓋原對象中相同屬性的值,不需覆蓋能夠進行判斷數組
//淺拷貝的方法 var extend = function(to, from) { for (var property in from) { //if(to.hasOwnProperty(property)) continue; //不須要覆蓋能夠執行該方法 if(!from.hasOwnProperty(property)) continue; Object.defineProperty(to,property,Object.getOwnPropertyDescriptor(from,property)); } return to; }; var aa = { name: 'ou', language: [ 'chinese' ] }; var bb = {}; bb = extend(bb, aa); console.log('aa---', aa, 'bb---', bb); bb.name = 'ming'; bb.language[0] = 'english'; console.log('aa---', aa, 'bb---', bb);
ps:深拷貝涉及到比較複雜的數據類型的判斷,性能優化
可遍歷的:Object、Array 、Map、Set函數
不可遍歷的:Bool、Number、String、Date、Error等性能
還有正則、克隆函數等優化
//簡單對對象類型進行判斷 var extend = function(to, from) { for (var property in from) { if (typeof from[property] === 'object') { let cloneTarget = Array.isArray(from[property]) ? [] : {}; //進行判斷,屬性的值是對象仍是數組 for (var key in from[property]) { cloneTarget[key] = from[property][key]; } to[property] = cloneTarget; } else { Object.defineProperty(to, property, Object.getOwnPropertyDescriptor(from, property)); } } return to; };