一步一步实现Javascript深克隆

步骤一:实现简单的递归克隆

function deepCopy(source) {
  return (function _copy(parent) {
    var child;
    for (var i in parent) {
        if (parent.hasOwnProperty(i)) {
            child[i] = _copy(parent[i]);
        } else {
            child = parent;
        }
    }
    return child;
  })(source)
}
复制代码

存在的问题

  • 未处理Array,Date,Function等特殊对象
  • 复制的对象的constructor都是指向Object构造函数
  • 存在循环引用问题

步骤二:处理特殊对象及constructor指向问题

function getType(obj) {
  var typeString = Object.prototype.toString.call(obj);
  return typeString.substring(8, typeString.length - 1);
}

function deepCopy(source) {

  return (function _copy(parent) {

    var child;

    switch (getType(parent)) {
      case 'Object':
          // 处理对象原型,指向父类的constructor
          child = Object.create(Object.getPrototypeOf(parent));
          for (var i in parent) {
            if (parent.hasOwnProperty(i)) {
              child[i] = _copy(parent[i]);
            }
          }
        break;
      default:
        child = parent;
    }

    return child;

  })(source)
}
复制代码

存在的问题

  • 存在循环引用问题

步骤三:处理循环引用问题

function getType(obj) {
  var typeString = Object.prototype.toString.call(obj);
  return typeString.substring(8, typeString.length - 1);
}

function deepCopy(source) {

  var copyedList = [];

  return (function _copy(parent) {

    var child;

    switch (getType(parent)) {
      case 'Object':
        // 是否已经克隆过了
        var isCopyIndex = copyedList.indexOf(parent);
        if (isCopyIndex >= 0) {
          child = copyedList[isCopyIndex]
        } else {
          copyedList.push(parent);
          // 处理对象原型,指向父类的constructor
          child = Object.create(Object.getPrototypeOf(parent));
          for (var i in parent) {
            if (parent.hasOwnProperty(i)) {
              child[i] = _copy(parent[i]);
            }
          }
        }
        break;
      default:
        child = parent;
    }

    return child;

  })(source)
}
复制代码

结束语

其实仍是有一些问题javascript

  • 存在爆栈的问题
  • 边界问题未处理
相关文章
相关标签/搜索