And the difference between deep and shallow copy implementation copies

A data type

Data into basic data type (String, Number, Boolean, Null, Undefined, Symbol) and object type data.

  • Characteristics of the basic data types: data is stored directly on the stack (Stack) of
  • Reference data types of features: storage is the object reference on the stack, the real data stored in the heap memory

Reference data type is stored in the stack pointer, the pointer to the start address of the stack entity. When the interpreter to find reference value, it will first retrieve its address on the stack, obtained from the heap after obtaining the address of the entity.

Second, the difference between the deep copy and shallow copy

Deep and shallow copy is a copy referenced only for this data type Object and Array.

Deep and shallow copy copy schematic approximately as follows:

Shallow copy copy only a pointer to an object, rather than copying the object itself, or the old and new objects share the same memory. But deep copy would otherwise create an identical objects, the new object with the original object is not shared memory, modify the new object is not to change the original object

Third, the difference between assignments and shallow copy

  • When we put a new object is assigned to a variable, Fu is actually the address of the object on the stack, rather than the data stack. That is, two objects point to the same memory space, regardless of which object is changed, the contents are actually changing the storage space, so the two objects are linked.

  • Shallow copy is bitwise copy of the object, it creates a new object that has an exact copy of the original object's property value. If the attribute is a value of the basic type of basic types, copied; if the attribute is a memory address (a reference type), the memory address is copied, so if one of the objects of this address is changed, it will affect the other object. That is just the default copy constructor object shallow copy copy (turn-by-member copy), copy an object that is only space without copying resources.

Let's look at two examples, comparative evaluation and shallow copy of the original object will bring what changes?

// 对象赋值
 var obj1 = {
    'name' : 'zhangsan',
    'age' :  '18',
    'language' : [1,[2,3],[4,5]],
};
var obj2 = obj1;
obj2.name = "lisi";
obj2.language[1] = ["二","三"];
console.log('obj1',obj1)
console.log('obj2',obj2)
// 浅拷贝
 var obj1 = {
    'name' : 'zhangsan',
    'age' :  '18',
    'language' : [1,[2,3],[4,5]],
};
 var obj3 = shallowCopy(obj1);
 obj3.name = "lisi";
 obj3.language[1] = ["二","三"];
 function shallowCopy(src) {
    var dst = {};
    for (var prop in src) {
        if (src.hasOwnProperty(prop)) {
            dst[prop] = src[prop];
        }
    }
    return dst;
}
console.log('obj1',obj1)
console.log('obj3',obj3)

In the above example, the original data is OBJ1, obj2 assignment is obtained, and the obtained obj3 shallow copy. We can clearly see the impact of the original data, details, please read the following table:

Fourth, the shallow copy implementation

  • 1.Object.assign ()
    Object.assign () method can be any of a plurality of source object itself may be enumerated attribute copy to the target object, the target object and then returns. However Object.assign () shallow copy is performed, the copy attribute is a reference to an object, rather than the object itself.
var obj = { a: {a: "kobe", b: 39} };
var initalObj = Object.assign({}, obj);
initalObj.a.a = "wade";
console.log(obj.a.a); //wade

Note: When the object when only one layer is deep copy

let obj = {
    username: 'kobe'
    };
let obj2 = Object.assign({},obj);
obj2.username = 'wade';
console.log(obj);//{username: "kobe"}

Modify the new object will change to the original object:

  • 2.Array.prototype.concat()
let arr = [1, 3, {
    username: 'kobe'
    }];
let arr2=arr.concat();    
arr2[2].username = 'wade';
console.log(arr);

Modify the new object will change to the original object:
Here Insert Picture Description

  • 3.Array.prototype.slice()
let arr = [1, 3, {
   username: ' kobe'
   }];
let arr3 = arr.slice();
arr3[2].username = 'wade'
console.log(arr);

Also new object will be changed to modify the original object:
Here Insert Picture Description
Supplement on slice and concat method of the Array: Array of slice and concat method does not modify the original array, returns only a pale copy of a new array element of the original array.

The elements of the original array in accordance with the following rules will be copied:

  • If the element is an object reference (not the actual object), slice will copy the object reference to the new array. Two objects references refer to the same object. If the referenced object is changed, the new and original arrays of this element will change.
  • For strings, numbers and Boolean values ​​for (not String, Number or Boolean object), slice these values ​​will be copied to the new array. Modify these strings or numbers or a Boolean value in another array, the array will not affect the other.

This passage may be obscure, we give an example, the example above small modification:

let arr = [1, 3, {
    username: ' kobe'
    }];
let arr3 = arr.slice();
arr3[1] = 2
console.log(arr,arr3);

Here Insert Picture Description

Fifth, the implementation of deep copy

  • 1.JSON.parse(JSON.stringify())
let arr = [1, 3, {
  username: ' kobe'
}];
let arr4 = JSON.parse(JSON.stringify(arr));
arr4[2].username = 'duncan'; 
console.log(arr, arr4)

Here Insert Picture Description
Principle: with JSON.stringify the object into a JSON string, and then JSON.parse () to parse the string into an object, a visit to a new object is created, and the object will open up new stack, to achieve deep copy .

While this method may be implemented array or object deep copy, but not handler

let arr = [1, 3, {
    username: ' kobe'
},function(){}];
let arr4 = JSON.parse(JSON.stringify(arr));
arr4[2].username = 'duncan'; 
console.log(arr, arr4)

Here Insert Picture Description
This is because the JSON.stringify () method is a JavaScript value (object or array) is converted to a JSON string, not accept the function

  • 2. Handwritten recursive
    recursive method to achieve a deep clone Principle: traverse the object, until the array is inside the basic data types, and then to copy, is deep copy
//定义检测数据类型的功能函数
function checkedType(target) {
  return Object.prototype.toString.call(target).slice(8, -1)
}
//实现深度克隆---对象/数组
function clone(target) {
  //判断拷贝的数据类型
  //初始化变量result 成为最终克隆的数据
  let result,
    targetType = checkedType(target)
  if (targetType === 'Object') {
    result = {}
  } else if (targetType === 'Array') {
    result = []
  } else {
    return target
  }
  //遍历目标数据
  for (let i in target) {
    //获取遍历数据结构的每一项值。
    let value = target[i]
    //判断目标结构里的每一值是否存在对象/数组
    if (checkedType(value) === 'Object' || checkedType(value) === 'Array') {
      //对象/数组里嵌套了对象/数组
      //继续遍历获取到value值
      result[i] = clone(value)
    } else {
      //获取到value值是基本的数据类型或者是函数。
      result[i] = value
    }
  }
  return result
}
  • 3. lodash library
    The library is also available _.cloneDeep used to make Deep Copy
var _ = require('lodash');
var obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f);
// false
  • 3. Use the Object.create () method

Directly var newObj = Object.create (oldObj), you can achieve the effect of a deep copy.

function deepClone(initalObj, finalObj) {    
  var obj = finalObj || {};    
  for (var i in initalObj) {        
    var prop = initalObj[i];        // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
    if(prop === obj) {            
      continue;
    }        
    if (typeof prop === 'object') {
      obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
    } else {
      obj[i] = prop;
    }
  }    
  return obj;
}
  • 6、jquery

jquery has provided a $ .extend can be used for Deep Copy.

var $ = require('jquery');
var obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
var obj2 = $.extend(true, {}, obj1);
console.log(obj1.b.f === obj2.b.f);
// false
Published 149 original articles · won praise 166 · views 40000 +

Guess you like

Origin blog.csdn.net/weixin_44369568/article/details/101515407