javascript 深拷贝

javascript的引用数据类型,实际存储是存储在堆中的,会有一个指向它的地址,这个地址,与简单数据类型一样存储在栈中。
所以,对于引用类型来说,简单的赋值操作,都只是赋值栈中的引用地址,指向的堆内容,永远是相同的。俗称浅拷贝。

JSON.stringify和JSON.parse实现深拷贝
缺点:毁掉原型链。丢失对象的constructor。全部变成Object。同时如果源对象中就有值为json字符串的属性,那将改变对象结构

Object.create()
Object.create()方法创建一个新对象,使用现有的对象来提供新创建对象的原型对象__proto__
缺点:改变了对象的结构。同时对引用类型也是浅拷贝,只复制一层

function Shape() {
  this.x = 0;
  this.y = 0;
}
Shape.prototype.move = function(x, y) {
  this.x += x;
  this.y += y;
  console.info('Shape moved.');
};
var a = new Shape()
var b = Object.create(a)
var c = {'a':a}
var d = Object.create(c)

分别打印a、b两个对象
javascript 深拷贝_第1张图片

javascript 深拷贝_第2张图片

javascript 深拷贝_第3张图片

另外:
lodash提供cloneDeep()用来做深拷贝
jQuery提供$.extend可以用来做深拷贝

自写深拷贝

function deepCopy(_target) {
  //闭包形式规避互相引用
  var _targetList = []
  var _copyList = []
    
  function _dcopy(_target){
    const index = _targetList.findIndex((e) => {
      return e === _target
    })
    if(-1 < index){
      return _targetList[index]
    }else{
      _targetList.push(_target)
    }
    var _copy = Array.isArray(_target) ? [] : {};
    if (_target && typeof _target === "object") {
      for (var i in _target) {
        if (_target.hasOwnProperty(i)) {
          const prop = _target[i]
          if (prop && typeof prop === "object") {
            _copy[i] = _dcopy(prop)
          } else {
            _copy[i] = prop;
          }
        }
      }
    }
    _copyList.push(_copy)
    return _copy; 
  } 
  return _dcopy(_target)
}

你可能感兴趣的:(javascript)