【JavaScript】深拷贝

为了实现一个函数 clone ,可以对 JavaScript 中 5 种主要的数据类型 (包括 Number、 String 、 Object、 Array、 Boolean )进行值(深)复制。

思路解释

首先根据题意要对5种数据类型进行深拷贝,那么就必须首先进行判断其为数据类型,使用instanceof进行判断,然后要对其进行分类复制,因为不仅要对表层数据进行拷贝,还要对包含在内的元素进行深拷贝,因此就需要使用到递归,通过递归实现深层次的拷贝(比如Object),拷贝后返回值存储在其浅层的索引中,最后等调用栈中的所有递归函数执行完毕,返回result,即完成了深拷贝,也称为深复制

代码实现

function clone(obj) {
  var result
  if (obj instanceof Array) {
    var i = obj.length
    result = [] // 向空的数组中复制内容
    while (i--) {
      result[i] = clone(obj[i]) // 递归克隆返回值
    }
    return result
  } else if (obj instanceof Object) {
    result = {} // 向空的对象中复制内容
    for (let k in obj) {
      result[k] = clone(obj[k]) // 递归克隆返回值
    }
    return result
  } else {
    return (result = obj) // 值类型直接返回
  }
}
var arr = [1, { a: 100 }, null]
var obj = { a: 100, b: true, c: { d: 'Hello' } }
var num = 200
console.log(clone(arr))
console.log(clone(obj))
console.log(clone(num))

完整实现

完整实现需要对所有数据类型进行判断,包括函数、日期对象、正则等。

function deepClone(obj) {
  // 过滤特殊情况
  if (obj === null) return null
  if (typeof obj !== 'object') return obj
  if (obj instanceof RegExp) {
    return new RegExp(obj)
  }
  if (obj instanceof Date) {
    return new Date(obj)
  }
  if (obj instanceof Function) {
    return new Function(obj)
  }
  // let newObj = {}
  // let newObj = new Object()
  // 不直接创建空对象目的:克隆的结果和之前保持相同的所属类
  let newObj = new obj.constructor()
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = deepClone(obj[key])
    }
  }
  return newObj
}
var obj = { a: 100, b: [1, 2, 3], c: { d: 'Hello' }, d: /^\d+$/ }
let obj2 = deepClone(obj)
console.log(obj, obj2)
console.log(obj === obj2)
console.log(obj.c === obj2.c)

posted @ 2020-07-15 18:48  努力挣钱的小鑫  阅读(246)  评论(1编辑  收藏  举报