Object assignment, shallow copy and deep copy

Note: The deep and shallow copies mentioned here are all described on the reference data type.

assignment

Copy the memory address directly (the new object changes, and the original object also changes)

The following newObj directly copies the memory address of obj, and they point to the same object, so modifying any attribute will affect each other.

const obj = {
  name: '小明',
  hobbies:['唱','跳','rap']
};
const newObj = obj
newObj.name = '张三'
newObj.hobbies[0] = '打篮球'
console.log(JSON.stringify(obj));
// {"name":"张三","hobbies":["打篮球","跳","rap"]}
console.log(JSON.stringify(newObj));
// {"name":"张三","hobbies":["打篮球","跳","rap"]}

shallow copy

The basic data type is to directly copy the value, and the reference data type is to copy the memory address

The following newObj, for the name attribute, directly copies the value; for the hobbies attribute, it copies the memory address.

ES6 spread operator implementation

const obj = {
  name: '小明',
  hobbies:['唱','跳','rap']
};
// 浅拷贝obj对象
const newObj = {...obj}
newObj.name = '张三'
newObj.hobbies[0] = '打篮球'
console.log(JSON.stringify(obj));
// {"name":"小明","hobbies":["打篮球","跳","rap"]}
console.log(JSON.stringify(newObj));
// {"name":"张三","hobbies":["打篮球","跳","rap"]}

Object.assign implementation

const obj = {
  name: '小明',
  hobbies: ['唱', '跳', 'rap']
};
// 浅拷贝obj对象
const newObj = Object.assign({},obj)
newObj.name = '张三'
newObj.hobbies[0] = '打篮球'
console.log(JSON.stringify(obj));
// {"name":"小明","hobbies":["打篮球","跳","rap"]}
console.log(JSON.stringify(newObj));
// {"name":"张三","hobbies":["打篮球","跳","rap"]}

ShallowCopy function implementation

const obj = {
  name: '小明',
  hobbies: ['唱', '跳', 'rap']
};
const newObj = shallowCopy(obj)
newObj.name = '张三'
newObj.hobbies[0] = '打篮球'
console.log(JSON.stringify(obj));
// {"name":"小明","hobbies":["打篮球","跳","rap"]}
console.log(JSON.stringify(newObj));
// {"name":"张三","hobbies":["打篮球","跳","rap"]}

// 浅拷贝函数
function shallowCopy(obj){
  const newObj = {}
  for(let key in obj){
    newObj[key] = obj[key]
  }
  return newObj
}

deep copy

Open up a new space directly in the heap memory (the new object changes, the original object remains unchanged)

JSON.parse and JSON.stringify implementation

The following newObj points to a new object that is exactly the same as obj. Whether it is modifying the basic type data in newObj or the reference type data, obj will not change.

const obj = {
  name: '小明',
  hobbies:['唱','跳','rap']
};
// 深拷贝obj对象
const newObj = JSON.parse(JSON.stringify(obj))
newObj.name = '张三'
newObj.hobbies[0] = '打篮球'
console.log(JSON.stringify(obj));
// {"name":"小明","hobbies":["唱","跳","rap"]}
console.log(JSON.stringify(newObj));
// {"name":"张三","hobbies":["打篮球","跳","rap"]}

However, the JSON.stringify method has a disadvantage: if the data contains functions or undefined, their key-value pairs will be lost after serialization.

const obj = {
  name: '小明',
  hobbies: ['唱', '跳', 'rap'],
  fn() {
    console.log(123);
  },
  age: undefined
};
const newObj = JSON.parse(JSON.stringify(obj))
console.log(newObj);
// 输出的结果没有fn和age属性

implementation of deepCopy function

const obj = {
  name: '小明',
  hobbies: ['唱', '跳', 'rap']
};
const newObj = deepCopy(obj)
newObj.name = '张三'
newObj.hobbies[0] = '打篮球'
console.log(JSON.stringify(obj));
// {"name":"小明","hobbies":["唱","跳","rap"]}
console.log(JSON.stringify(newObj));
// {"name":"张三","hobbies":["打篮球","跳","rap"]}

// 深拷贝函数
function deepCopy(obj) {
  if (typeof (obj) !== 'object' || typeof (obj) == null) return obj
  const newObj = Array.isArray(obj) ? [] : {}
  for (let key in obj) {
    // 递归调用
    newObj[key] = deepCopy(obj[key])
  }
  return newObj
}

Guess you like

Origin blog.csdn.net/qq_52607834/article/details/129404355