開門見山,有人叫對象的複製爲深複製淺複製,也有人叫深拷貝淺拷貝。
其實都是copy。javascript
深拷貝(遞歸複製,複製全部層級,獨立副本,一個徹底和原來對象屬性無關的副本)
返回對象:一個。
傳入對象:一個。
條件:JSON安全的對象,能夠序列化爲JSON字符串,而且能夠解析爲新的字符串。
深拷貝算法:前端
function deepCopy(data){ let memory = null; const type = Object.prototype.toString.call(data); if (type === "[object Array]"){ memory = [] for (let i=0 ;i<data.length;i++){ memory.push(deepCopy(data[i])) } }else if (type === "[object Object]"){ memory = {} Object.keys[data].forEach((key)=>{ memory[key] = data[key] }) }else{ return data; } return memory; }
jQuery深拷貝:var copiedObject = jQuery.extend(true, {}, originalObject)
java
es6深拷貝:var copiedObject= JSON.parse(JSON.stringify(originalObject));
git
深拷貝是遞歸複製,新複製的對象與原對象是徹底獨立的兩個對象,它們指向不一樣的內存地址,作set不會影響到對方。es6
淺拷貝(單次複製,複製最高層級,引用副本,一個基於對原對象屬性引用的副本)
返回對象:一個。
傳入對象:一個或多個。
條件:無。github
jQuery淺拷貝:var copiedObject = jQuery.extend({}, originalObject)
算法
es6淺拷貝:var copiedObject = Object.assign({},originalObject)
segmentfault
es7淺拷貝:var copiedObject = {...originalObject}
數組
淺拷貝算法:安全
function shallowCopyObj(original){ let copy = {} Object.keys(original).forEach(key=>{ copy[key] = original[key] }) return copy }
因爲javascript的對象是存地址的,因此淺複製的對象與原對象,都指向同一個內存地址,屬於引用複製,作set會影響到對方。
實驗:
①普通屬性修改:深拷貝和淺拷貝均可以知足對象的複製。
普通屬性是指value值爲非Array,Object類型的數據類型,也就是Number,String,Boolean等基本數據類型。
緣由:基本數據類型屬於值傳遞。
var obj = {foo:1}; var deepCopyObj = JSON.parse(JSON.stringify(obj)); deepCopyObj.foo = 2; console.log("obj.foo:",obj.foo);//1 console.log("deepCopyObj.foo:",deepCopyObj.foo);//2
var obj = {foo:1}; var shallowCopyObj = Object.assign({},obj); shallowCopyObj.foo = 2; console.log("obj.foo:",obj.foo);//1 console.log("shallowCopyObj.foo:",shallowCopyObj.foo);//2
②高級屬性修改:深拷貝知足對象的複製,淺拷貝影響原數組。
高級屬性是指Array,Object數據類型。
緣由:基本數據類型屬於引用傳遞。
var obj = {foo:1,bar:{baz:1}}; var deepCopyObj = JSON.parse(JSON.stringify(obj)); deepCopyObj.bar.baz = 2; console.log("obj.bar.baz:",obj.bar.baz);//1 console.log("deepCopyObj.bar.baz:",deepCopyObj.bar.baz);//2
var obj = {foo:1,bar:{baz:1}}; var shallowCopyObj = Object.assign({},obj); shallowCopyObj.bar.baz = 2; console.log("obj.bar.baz:",obj.bar.baz);//2 Attention! console.log("shallowCopyObj.bar.baz:",shallowCopyObj.bar.baz);//2
印象中const也是保持變量地址不變的操做,那麼es6中的let和const對於對象的深淺拷貝有影響嗎?
也就是將上面代碼中的var替換爲let和const。
實驗結果是let和const不會影響深淺拷貝的結果,由於let強調塊做用域,而const強調變量總體地址空間的不變性。
關於對象的深淺拷貝,暫且探索到這裏,後續有新發現再進行補充。
謝謝您的閱讀~
期待和你們交流,共同進步,歡迎你們加入我建立的與前端開發密切相關的技術討論小組:
- SegmentFault技術圈:ES新規範語法糖
- SegmentFault專欄:趁你還年輕,作個優秀的前端工程師
- 知乎專欄:趁你還年輕,作個優秀的前端工程師
- Github博客: 趁你還年輕233的我的博客
- 前端開發QQ羣:660634678
- 微信公衆號: 人獸鬼 / excellent_developers
努力成爲優秀前端工程師!