说法是错误的,引用数据类型同时存放在堆与栈里面的,堆中存储对象,栈里面存储对象指向的指针。

赋值:就是对原对象的栈内存地址进行复制

// 对象赋值
let obj1 = {
    name: 'Chen',
    age: 18,
    hobby: ['see a film', 'write the code', 'play basketball', 'tourism']
}

let obj2 = obj1;
 = 'Forever';
obj2.hobby[1] = 'swim';
obj2.hobby[2] = 'alpinism';
console.log('obj1===>', obj1);
console.log('obj2===>', obj2);

ios object 之间赋值 给object赋值_ios object 之间赋值

浅拷贝:是对原对象的属性值进行精准复制,如果原对象的属性值是基本类型,那就是值的引用,所以浅拷贝后修改基本类型不会修改到原对象的,如果原对象属性值是引用类型,那么就是对引用类型属性值的栈内存的复制,所以修改引用类型属性值的时候会修改到原对象。

// 浅拷贝
let obj1 = {
    name: 'Chen',
    age: 18,
    hobby: ['see a film', 'write the code', 'play basketball', 'tourism']
}

let obj3 = {...obj1};
 = 'Forever';
obj3.hobby[1] = 'swim';
obj3.hobby[2] = 'alpinism';
console.log('obj1===>', obj1);
console.log('obj3===>', obj3);

ios object 之间赋值 给object赋值_javascript_02

赋值和浅拷贝的区别

  • 当我们把一个对象赋值给一个新的变量时,赋的其实是该对象的在栈中的地址,而不是堆中的数据。也就是两个对象指向的是同一个存储空间,无论哪个对象发生改变,其实都是改变的存储空间的内容,因此,两个对象是联动的
  • 浅拷贝则比赋值多了一层,把对象的值复制一份赋给一个新变量。当对象里的属性值是基础数据类型时,其中一个对象改变属性值,另一个对象不会受到影响;但是当对象里的属性值是引用数据类型时,那么这里面的引用数据类型就会是联动的,其中一个对象改变属性值,另一个对象相应的属性值就会发生改变。
    简单的说,浅拷贝就相当于给对象的第一层做了遍历赋值

深拷贝和浅拷贝的区别:浅拷贝主要是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,并对指针指向的内容进行拷贝,经过深拷贝后的指针是指向两个不同地址的指针。

因此一般对无引用类型的属性的兑现拷贝的时候使用浅拷贝就行,对复杂对象包含引用类型属性的时候使用深拷贝。

浅拷贝对象方法:

1.Object.assign({},obj)

要注意当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝,但是对象中有对象的时候,此方法,在二级属性以后就是浅拷贝。

ios object 之间赋值 给object赋值_javascript_03

ios object 之间赋值 给object赋值_javascript_04

2.obj1={...obj2}

深拷贝对象方法(简单方法):

1.JDON.parse(JSON.stringfy(obj))  无法拷贝undefined和Symbol,还会出现循环引用问题

2.手写深拷贝

使用for  in  遍历传入参数的属性值,如果值是基本类型直接复制,若是引用类型则递归调用本函数(附上引用类型的判断方法:xx instanceOf Object 和Array.isArray(xx))   存在问题是除了对象和数组,其他引用类型无法拷贝(Date等),Symbol也不能复制

后续继续补充...

function cloneDeep(obj) {
  if (!obj instanceof Object) {
    return;
  }
  let newObj = obj instanceof Array ? [] : {};
  for (let key in obj) {
    // 使用 .hasOwnProperty()判断一个对象是否包含自定义属性而不是原型链上的属性
    if (obj.hasOwnProperty(key)) {
      newObj[key] = obj[key] instanceof Object ? cloneDeep(obj[key]) : obj[key];
    }
  }
  return newObj;
}