一、前端深拷貝方法
深拷貝是指將一個對象完全複製到另一個對象中,兩個對象再無關聯。在前端開發中,如果不加區分地使用對象賦值,淺拷貝會讓開發者遭受到極大的困擾,因為它只會複製對象的引用,也就是說兩個對象會指向同一個值。為了避免這種情況,我們可以使用深拷貝。深拷貝可以通過JSON.parse() 和 JSON.stringify() 進行實現,這是最簡單的方法。
let obj = {a: 1, b: {c: 2}};
let newObj = JSON.parse(JSON.stringify(obj));
在上面的例子中,我們將對象 obj 深拷貝到 newObj 中,newObj 在內存中開闢了一塊新的地址,所以 obj 和 newObj 不會相互影響。
二、前端實現深拷貝的方式
除了使用JSON.parse() 和 JSON.stringify() 這種方法,我們還可以使用遞歸實現深拷貝。如下:
function deepClone(obj) {
const newObj = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key];
}
}
return newObj;
}
在這個方法中,我們使用 for…in 循環遍歷對象,使用 hasOwnProperty() 方法來判斷對象中是否有該屬性。如果是對象則再遞歸調用 deepClone() 方法,否則直接複製屬性。
三、前端深拷貝什麼意思
在前端開發中,深拷貝指的是將一個對象完全複製到另一個對象中,兩個對象再無關聯。通過深拷貝,我們可以避免因為對象引用而產生的一系列問題。
四、前端深拷貝和淺拷貝的區別
淺拷貝只是將對象的引用複製給了另一個對象,新對象和源對象共享同一塊內存空間,對新對象的修改會影響到源對象。而深拷貝則是將對象的值完全複製給了另一個對象,兩個對象再無任何關聯。
五、前端深拷貝缺陷
雖然使用遞歸實現的深拷貝可以完整地複製對象,但在實際開發中,它仍存在一些缺陷。
首先,遞歸實現的深拷貝中,遞歸層數過多會導致內存溢出問題。其次,該方法無法對 function、RegExp 等特殊對象進行拷貝。不過這些缺陷我們可以通過深入研究內部原理,針對不同的對象類型進行特定處理,來解決這些問題。
六、前端深拷貝函數
Lodash 是一個流行的JS庫,它提供了 _.cloneDeep() 方法,可以對任意對象進行深拷貝。使用如下:
const _ = require('lodash');
let obj = {a: 1, b: {c: 2}};
let newObj = _.cloneDeep(obj);
在這個方法中,我們使用了 Lodash 的 _.cloneDeep() 針對 obj 對象進行了深拷貝。
七、前端深拷貝實現
在面試中,有可能會遇到要求手寫深拷貝的面試題,而遞歸實現是最常見的手寫深拷貝方法。如下:
function deepClone(obj) {
const newObj = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key];
}
}
return newObj;
}
相較於之前的方法,這個方法在處理數組的時候,做了特殊處理。如果 obj 是數組類型,則新建一個空數組。在複製屬性的時候,我們判斷了 obj[key] 的類型,如果是數組,我們遞歸調用 deepClone() 方法。
八、前端深拷貝手寫方法
除了使用遞歸實現深拷貝外,我們還可以使用其他方法手寫深拷貝。如下:
function deepClone(obj) {
const cache = new WeakMap();
function clone(target) {
if (typeof target === 'object' && target !== null) {
if (cache.has(target)) {
return cache.get(target);
}
const newObj = Array.isArray(target) ? [] : {};
cache.set(target, newObj);
for (let key in target) {
if (target.hasOwnProperty(key)) {
newObj[key] = clone(target[key]);
}
}
return newObj;
} else {
return target;
}
}
return clone(obj);
}
在這個方法中,我們使用了 WeakMap() 來存儲已經拷貝過的對象。在遞歸的時候,如果對象已經存在於 WeakMap() 中,則直接返回緩存的對象。
九、前端深拷貝和淺拷貝的方法
在 JavaScript 中,淺拷貝常用的方法有 Object.assign() 和展開運算符。而深拷貝除了之前提到的遞歸實現和 Lodash 的 _.cloneDeep(), 還有 jQuery 的 $.extend() 方法和第三方庫 immer.js 等。
十、前端深拷貝內存溢出
由於遞歸實現深拷貝是通過不斷地創建臨時變量,所以在處理大型對象或多重嵌套對象時,可能會出現內存佔用過多、內存溢出等問題。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/293093.html
微信掃一掃
支付寶掃一掃