使用JSON.stringify的方式來實現深拷貝的弊端
弊端一:無法拷貝NaN、Infinity、undefined這類值
無法拷貝成功的原因:
對于JSON來說,它支持的數據類型只有null、string、number、boolean、Object、Array,所以對于它不支持的數據類型就會自動轉成null。
為什么undefined拷貝會丟失?
因為JSON不支持undefined這個數據類型,并且undefined相當于沒有定義,所以就無法拷貝成功。
例如下圖:我給obj.c設為undefined,但我沒有給obj.tttttttttt設置任何值,它也是undefined。
弊端二:無法拷貝循環引用
什么是循環引用
如下圖:目標對象的子孫屬性中,賦值了目標對線,就會導致循環引用。
對循環對象使用JSON.stringify進行深拷貝時會出現報錯
如下圖所示:
解決方案
解決方案的話,一般就是使用第三方庫的深拷貝方法處理啦。
不過下面我會介紹在自己手寫深拷貝的時候,如何去解決循環引用問題(為了面試)。
先上代碼:
function deepClone(target, mapObj = new WeakMap()) {let res;const typeStr = Object.prototype.toString.call(target);if(typeStr === '[object Object]') {res = {};} else if (typeStr === '[object Array]') {res = [];} else {return target;}Object.keys(target).forEach(key => {if(target.hasOwnProperty(key)) {if(typeof target[key] === 'object') {if (mapObj.get(target[key])) {res[key] = target[key]} else {mapObj.set(target[key], target[key]);res[key] = deepClone(target[key], mapObj);}} else {res[key] = target[key];}}})return res;
}
這里的話,主要是引用了weakMap來處理循環引用問題,因為weakMap支持key是一個對象。
手寫deepClone的話,就無需兼容上面弊端一的問題了,因為js是支持NaN、Infinity這些數據類型的。