在js中,怎麼用一行代碼實現深拷貝?它能夠實現: JSON.parse(JSON.stringify(obj))。
這行代碼的運行過程,就是利用 JSON.stringify 將js對象序列化(JSON字符串),再使用JSON.parse來反序列化(還原)js對象;序列化的做用是存儲和傳輸。(對象自己存儲的是一個地址映射,若是斷電,對象將不存在,因此要將對象的內容轉換成字符串的形式再保存在磁盤上)
不過,這種實現深拷貝的方法有侷限性,它只適用於通常數據的拷貝(對象、數組),有如下狀況須要注意:json
1.若是json裏面有時間對象,則序列化結果:時間對象=>字符串的形式;segmentfault
{ let obj = { age: 18, date: new Date() }; let objCopy = JSON.parse(JSON.stringify(obj)); console.log('obj', obj); console.log('objCopy', objCopy); console.log(typeof obj.date); // object console.log(typeof objCopy.date); // string }
2.若是json裏有RegExp、Error對象,則序列化的結果將只獲得空對象 RegExp、Error => {};數組
{ let obj = { age: 18, reg: new RegExp('\\w+'), err: new Error('error message') }; let objCopy = JSON.parse(JSON.stringify(obj)); console.log('obj', obj); console.log('objCopy', objCopy); }
3.若是json裏有 function,undefined,則序列化的結果會把 function,undefined 丟失;函數
{ let obj = { age: 18, fn: function () { console.log('fn'); }, hh: undefined }; let objCopy = JSON.parse(JSON.stringify(obj)); console.log('obj', obj); console.log('objCopy', objCopy); }
4.若是json裏有NaN、Infinity和-Infinity,則序列化的結果會變成null;this
{ let obj = { age: 18, hh: NaN, isInfinite: 1.7976931348623157E+10308, minusInfinity: -1.7976931348623157E+10308 }; let objCopy = JSON.parse(JSON.stringify(obj)); console.log('obj', obj); console.log('objCopy', objCopy); }
5.若是json裏有對象是由構造函數生成的,則序列化的結果會丟棄對象的 constructor;spa
{ function Person(name) { this.name = name; } let obj = { age: 18, p1: new Person('lxcan') }; let objCopy = JSON.parse(JSON.stringify(obj)); console.log('obj', obj); console.log('objCopy', objCopy); console.log(obj.p1.__proto__.constructor === Person); // true console.log(objCopy.p1.__proto__.constructor === Object); // true }
6.若是對象中存在循環引用的狀況也沒法實現深拷貝code
{ let obj = { age: 18 }; obj.obj = obj; let objCopy = JSON.parse(JSON.stringify(obj)); console.log('obj', obj); console.log('objCopy', objCopy); }
以上,若是拷貝的對象不涉及上面的狀況,能夠使用 JSON.parse(JSON.stringify(obj)) 實現深拷貝。
關於js深拷貝的相關知識以及更多解決方案,能夠閱讀這篇文章 深拷貝的終極探索(99%的人都不知道)對象