JavaScript对象类型数据深拷贝方法【主要解决JSON.parse(JSON.stringify()会去掉函数属性的问题】

文章目录

    • JavaScript对象类型数据深拷贝方法【主要解决JSON.parse(JSON.stringify()会去掉函数属性的问题】
    • 手写对象类型数据深拷贝方法deepClone
    • 小结

JavaScript对象类型数据深拷贝方法【主要解决JSON.parse(JSON.stringify()会去掉函数属性的问题】

正常情况下,在js中我们要对一个数组做深拷贝,最新想到的方法是JSON.parse(JSON.stringify(arr)),但是JSON.parse(JSON.stringify()会去掉属性中为函数的属性。

例如:

let arr = [
  {
    a: 1,
    b: 2,
    c: function () {
      console.log('111');
    }
  }
]
arr1 = JSON.parse(JSON.stringify(arr))
arr1[0].a = 100
console.log(arr, arr1);
// [ { a: 1, b: 2, c: [Function: c] } ] 
// [ { a: 100, b: 2 } ]

手写对象类型数据深拷贝方法deepClone

代码如下:

function deepClone(originValue) {
  // 如果不是对象类型且是null则直接将当前值返回
  if (typeof originValue !== 'object' || originValue == null) {
    return originValue;
  }

  const newObject = Array.isArray(originValue) ? [] : {}
  for (const key in originValue) {
    //  因为javascript没有将hasOwnProperty作为一个敏感词,所以我们很有可能将对象的一个属性命名为hasOwnProperty,
    // 这样一来就无法再使用对象原型的 hasOwnProperty 方法来判断属性是否是来自原型链。
    // 所以采用 Object.prototype.hasOwnProperty.call
    if (Object.prototype.hasOwnProperty.call(originValue, key)) {
      // 若是对象类型属性,递归调用deepClone,若是其他类型属性,则直接赋值
      if (typeof originValue[key] === 'object' && originValue[key] !== null) {
        newObject[key] = deepClone(originValue[key]);
      } else {
        newObject[key] = originValue[key];
      }
    }
  }

  return newObject
}

let arr = [
  {
    a: 1,
    b: 2,
    c: function () {
      console.log('111');
    }
  }
]
arr1 = deepClone(arr)
// arr1 = JSON.parse(JSON.stringify(arr))
arr1[0].a = 100
console.log(arr, arr1);
// [ { a: 1, b: 2, c: [Function: c] } ] 
// [ { a: 100, b: 2, c: [Function: c] } } ]
arr1[0].c() // 111

小结

如果对象数组中属性没有函数属性,可以使用JSON.parse(JSON.stringify(),但是如果有函数属性值,则使用自己写的deepClone方法。

你可能感兴趣的:(javascript,前端)