JS相关知识学习笔记(补充)——对象的直接赋值、浅拷贝和深拷贝

2021-05-22  本文已影响0人  喑宝儿
1、直接进行赋值

(1)对于一个复杂数据类型a,直接将它赋值给另一个变量b,两个变量将指向同一个地址,值会完全一样,改变任何一个变量的任何一个属性值,另一个也会随之改变

(2)先把a的值赋给b,之后再把另一个数据整体赋值给b,则a不变,b则指向新赋值的变量地址

var a = {
  name:'zs',
  age: 18
}
var b = a
console.log(a)  // {name: 'zs', age: 18}
console.log(b)  // {name: 'zs', age: 18}
b.name = 'ls'
console.log(a)  // {name: 'ls', age: 18}
console.log(b)  // {name: 'ls', age: 18}

b = [1, 2, 3]
console.log(a)  // {name: 'ls', age: 18}
console.log(b)  // [1, 2, 3]
2、对象的浅拷贝

对一个对象进行浅拷贝时:

对象中的简单数据类型,拷贝的时候会重新分配一个内存地址,修改新对象或旧对象的属性值,对另外一个没有任何影响

对象中的复杂数据类型,拷贝的时候依旧指向同一个内存地址,修改新对象或旧对象的属性值,另一个也会随之改变

var obj = {
  name:'zs',
  age: 18,
  msg: {
    hobby: 'sing'
  }
}

var o = {}

// 浅拷贝方式1
for (var k in obj) {
  o[k] = obj[k]
}

// 浅拷贝方式2
Object.assign(o, obj)

o.age = 20
o.msg.hobby = 'dance'

console.log(o)  // {name: 'zs', age: 20, msg: {hobby: 'dance'}}
console.log(obj)  // {name:'zs', age: 18, msg: {hobby: 'dance'}}

/** 单独修改了o对象中的普通数据类型age,修改o中的复杂数据类型,两个都被修改 */
3、对象的深拷贝

对一个对象进行深拷贝:

(1)对象中可能会有复杂数据类型,对于复杂数据类型得一层一层进行拷贝,需要用到递归

(2)数组和对象都属于复杂数据类型,因此要分情况进行判断讨论

(3)函数一般直接拷贝,避免内存浪费,最好指向同一地址,复用性强

var obj = {
  name:'zs',
  age: 18,
  msg: {
    hobby: 'sing',
    fruit: 'apple'
  }
}

var o = {}

function deepCopy(newObj, oldObj) {
  for (var k in oldObj) {
    var item = oldObj[k]
    
    if (item instanceof Array) {  // 先判断是不是数组,如果是,需要继续调用函数
      newObj[k] = []  // 准备一个空数组,作为下一层递归的第一个参数
      deepCopy(newObj[k], oldObj[k])
    } else if (item instanceof Object) {  // 先判断是不是对象,如果是,需要继续调用函数
      newObj[k] = {}  // 准备一个空对象,作为下一层递归的第一个参数
      deepCopy(newObj[k], oldObj[k])
    } else {  //  简单数据类型以及函数直接进行拷贝
      newObj[k] = oldObj[k]
    }
  }
}

deepCopy(o, obj)

o.msg.hobby = 'dance'
obj.msg.fruit = 'mongo'

console.log(o)  // {name: 'zs', age: 18, msg: {hobby: 'dance', fruit: 'apple'}}
console.log(obj)  // {name: 'zs', age: 18, msg: {hobby: 'sing', fruit: 'mongo'}}

/** 分别修改了o中的msg.hobby和obj中的msg.fruit,均修改成功,相互不影响 */
上一篇 下一篇

猜你喜欢

热点阅读