js 深度克隆实例

数据模型:

      const a = {foo: {}, bar: []}
      const b = {foo: {}, bar: []}
      a.foo.b = b
      a.bar.push(b)
      b.foo.a = a
      b.bar.push(a)

方案一:

      let clone = function (data) {
        const cmap = new Map()
        let _clone = function (d) {
          if (cmap.has(d)) {
            return cmap.get(d)
          }
          if (Array.isArray(d)) {
            const result = new Array(d.length)
            cmap.set(d, result)
            d.forEach((item, idx) => {
              result[idx] = _clone(item)
            })
            return result
          } else if (d === null) {
            return d
          } else if (d instanceof Date) {
            return new Date(d)
          } else if (typeof d === 'object') {
            const result = {}
            cmap.set(d, result)
            Object.keys(d).forEach((item, idx) => {
              result[item] = _clone(d[item])
            })
            return result
          }
          return cmap
        }
        return _clone(data)
      }
      console.log(clone(b))

方案二:

    Object.prototype.Clone = function () {
        var objClone
        var cloneKey = '___deep_clone___'
        if (this.constructor === Object) {
          objClone = new this.constructor()
        } else {
          objClone = new this.constructor(this.valueOf())
        }
        this[cloneKey] = objClone
        for (var key in this) {
          if (key === cloneKey) continue
          if (objClone[key] !== this[key]) {
            if (typeof (this[key]) === 'object') {
              if (this[key][cloneKey]) {
                objClone[key] = this[key][cloneKey]
              } else {
                objClone[key] = this[key].Clone()
              }
            } else {
              objClone[key] = this[key]
            }
          }
        }
        delete this[cloneKey]
        return objClone
      }
     console.log(b.Clone())

方案三:

deepCopy (obj, deep) {
    let _self = this
    // 类型判断
    let isArray = (item) => {
      return Object.prototype.toString.call(obj) === '[object Array]'
    }

    if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) {
      return obj
    }

    if (typeof obj === 'function') {
      return new Function('return ' + obj.toString())()
    } else {
      var name = null
      var target = isArray(obj) ? [] : {}
      let value = null

      for (name in obj) {
        value = obj[name]
        if (value === obj) {
          continue
        }

        if (deep && (isArray(value) || typeof value === 'object')) {
          target[name] = _self.deepCopy(value, deep)
        } else {
          target[name] = value
        }
      }
      return target
    }
  }
posted @ 2017-08-10 14:54  唐岗  阅读(292)  评论(0)    收藏  举报