天天看點

前端面試之js 中常見的深拷貝的方法

前端小夥伴們在面試的時候,經常會遇到問JS深拷貝的知識點,是以特地寫這篇部落格,也算是給自己積累一些知識點。

目前有5種經常提到的深拷貝的方法:

1、通過 JSON 對象實作深拷貝

function deepClone(data) {
    let _data = JSON.stringify(data),
        dataClone = JSON.parse(_data);
    return dataClone;
};
           

2、通過jQuery的extend方法實作深拷貝

3、使用遞歸的方式實作深拷貝

//使用遞歸的方式實作數組、對象的深拷貝
function _deepClone(source) {
  let target;
  if (typeof source === 'object') {
    target = Array.isArray(source) ? [] : {}
    for (let key in source) {
      if (source.hasOwnProperty(key)) {
        if (typeof source[key] !== 'object') {
          target[key] = source[key]
        } else {
          target[key] = _deepClone(source[key])
        }
      }
    }
  } else {
    target = source
  }
  return target
}
           

4、Object.assign()拷貝

當對象中隻有一級屬性,沒有二級屬性的時候,此方法為深拷貝,

但是對象中有對象的時候,此方法,在二級屬性以後就是淺拷貝。

//針對深拷貝,需要使用其他辦法,因為 Object.assign()拷貝的是屬性值。假如源對象的屬性值是一個對象的引用,那麼它也隻指向那個引用。
let obj1 = { a: 0 , b: { c: 0}}; 
let obj2 = Object.assign({}, obj1); 
console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}} 

obj1.a = 1; 
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}} 
console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}} 

obj2.a = 2; 
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}} 
console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 0}}
 
obj2.b.c = 3; 
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 3}} 
console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 3}} 
最後一次指派的時候,b是值是對象的引用,隻要修改任意一個,其他的也會受影響

// Deep Clone (深拷貝)
obj1 = { a: 0 , b: { c: 0}}; 
let obj3 = JSON.parse(JSON.stringify(obj1)); 
obj1.a = 4; 
obj1.b.c = 4; 
console.log(JSON.stringify(obj3)); // { a: 0, b: { c: 0}}
           

5、lodash函數庫實作深拷貝

多數時候,我會用lodash提供的函數庫來調用,畢竟封裝過的,健壯性應該還是ok的,哈哈~

lodash很熱門的函數庫,提供了

lodash.cloneDeep()

實作深拷貝

參考文檔:

https://www.cnblogs.com/lijuntao/p/13066834.html

https://www.cnblogs.com/sweet-ice/p/10599011.html