这是我参与「第五届青训营 」伴学笔记创作活动的第 11 天
深拷贝和浅拷贝 这两个概念是在项目中比较常见的,在很多时候,都会遇到拷贝的问题,我们总是需要将一个对象赋值到另一个对象上,但可能会在改变新赋值对象的时候,忽略掉我是否之后还需要用到原来的对象,那么就会出现当改变新赋值对象的某一个属性时,也同时改变了原对象,在这里,我们需要注意一点,那就是"引用"和"值"是什么,在学c的时候,涉及到了一个指针的概念,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。所以,这里的值就是对象的值,而引用就是指向存储这个值的地址。
浅拷贝: (拷贝一层) 如果对象的属性是基本类型,拷贝的就是基本类型的值,如果属性 是引用类型, 拷贝的就是内存地址,两个对象用的是同一个内存,修改其中一个的值,另一个 也跟着改变. 实现浅拷贝的方法:
-
Object.assign(对象、数组)参数:
target--->目标对象
source--->源对象
返回值 :target,即目标对象
<!-- 对象 --> const obj = { name: "lin", }; const newObj = Object.assign({}, obj); obj.name = "xxx"; // 改变原来的对象 console.log(newObj); // { name: 'lin' } 新对象不变 console.log(obj == newObj); // false 两者指向不同地址 <!-- 数组 --> const arr = [1, 2, 3]; const newArr = Object.assign([], arr); arr[2] = 100; // 改变原来的数组 console.log(newArr); // [1, 2, 3] // 新数组不变 console.log(arr == newArr); // false 两者指向不同地址 -
扩展运算符(对象、数组)<!-- 对象 --> const obj = { name: "lin", }; const newObj = { ...obj }; obj.name = "xxx"; // 改变原来的对象 console.log(newObj); // { name: 'lin' } // 新对象不变 console.log(obj == newObj); // false 两者指向不同地址 <!-- 数组 --> const arr = [1, 2, 3]; const newArr = [...arr]; arr[2] = 100; // 改变原来的数组 console.log(newArr); // [1, 2, 3] // 新数组不变 console.log(arr == newArr); // false 两者指向不同地址 -
slice(数组)参数:
start:开始位置的索引
end:结束位置的索引(但不包含该索引位置的元素)
const arr = [1, 2, 3]; const newArr = arr.slice(0); arr[2] = 100; // 改变原来的数组 console.log(newArr); // [1, 2, 3] // 新数组不变 console.log(arr == newArr); // false 两者指向不同地址 -
concat(数组)const arr = [1, 2, 3]; const newArr = [].concat(arr); arr[2] = 100; // 改变原来的数组 console.log(newArr); // [1, 2, 3] // 新数组不变 console.log(arr == newArr); // false 两者指向不同地址 -
Array.from(数组)将一个类数组对象(有 length 属性的)或者可遍历对象转换成一个真正的数组
const arr = [1, 2, 3]; const newArr = Array.from(arr); arr[2] = 100; // 改变原来的数组 console.log(newArr); // [1, 2, 3] // 新数组不变 console.log(arr == newArr); // false 两者指向不同地址