Js克隆对象

Js克隆对象

1 浅复制

具体方法

// 数组
Array.prototype.slice
const oldArr = new Array(100).fill(null).map(() => Math.random() * 100 | 0)
const newArr = oldArr.slice()

// 普通对象
Object.assign
const oldObj = new Object() // plain object
const newObj = Object.assign({}, oldObj)

2 深复制

1) 转字符串再还原

function deepClone(obj) {
    return JSON.parse(JSON.stringify(obj))
}

2) 便利对象,递归克隆

function deepClone(obj) {
    if ( typeof obj !==  'object' ) {
        return obj
    }
    const ret = Array.isArray(obj) ? [] : {}
    for ( let i  in obj ) {
        ret[i] = deepClone(obj[i])
    }
    return ret
}

3)循环引用对象

如果采用以上两种克隆方式,遇到循环引用对象会导致报错

function updateClone(obj) {
  const map = new Map();
  function deepClone(obj) {
    if (typeof obj !== 'object') {
      return obj;
    }
    const ret = Array.isArray(obj) ? [] : {};
    for (let i in obj) {
      const dist = obj[i];
      if (map.has(dist)) {
        continue;
      } else {
        map.set(dist, true);
        ret[i] = dist;
      }
    }
    return ret;
  }
  return deepClone(obj);
}

4)难克隆对象,甚至无法克隆对象

比如Date, Function, Error或者自定义的一些class构造对象

const oldDate = new Date()
const newDate = new Date(+oldDate)

// Function 使用toString,但是考虑到可能bind有些context,而且函数的作用域链,这些没法搞
// Error stack message

5)对象属性key异常情况

属性不可枚举

Object.getOwnPropertyDescriptors({a:1})

image
这个可以通过使用Object.getOwnPropertyNames解决

遍历了原型链上属性(方法)

某些同学写代码不注意,直接Object.prototype.xx = xx
这个可以也通过使用Object.getOwnPropertyNames解决

posted @ 2020-09-27 13:54  彩虹刀法  阅读(37)  评论(0编辑  收藏  举报