typora-root-url: images
typora-copy-images-to: images
深拷贝的实现:
深浅拷贝的基本认识
深浅拷贝问题其实就是基本类型和引用类型数据拷贝的问题。因为基本类型的数据大小是固定的,所以他保存在栈内存中;而引用类型的数据大小不固定,因而保存在堆内存中,单引用类型在栈内存中只保存一个指向堆内存的指针。
浅拷贝:对于浅拷贝来说,如果拷贝基本类型,那么就等于赋值一样,会直接拷贝其本身;但如果拷贝的是引用类型,就只会拷贝一层,如果 原对象发生改变,那么拷贝对象也会发生改变。
深拷贝:深拷贝的话就会拷贝多层,嵌套的对象也会被拷贝出来,相当于开辟一个新的内存地址用于存放拷贝的对象。
首先创造一个对象
第一种:ES6的Object.assign()方法
针对于对象只有一层的,不能实现真正的深拷贝。对象有多层的不能使用此方法。
Object.assign({},obj)的意思是先建立一个空对象{},接着把obj
中所有的属性复制过去,所以obj1会长得跟
obj一样,这时候再修改
obj1.也不会影响
obj。
Object.assign()
let obj1 = {};
Object.assign(obj1, obj);
obj1.name = "小辣椒";
console.log(obj, obj1);
输出结果:
**第二种:JSON实现深拷贝
用JSON.stringify
把对象转成字符串,再用JSON.parse
把字符串转成新的对象。但这个方法缺点就是会造成方法的丢失
let obj1 = JSON.stringify(obj);
obj1 = JSON.parse(obj1);
// console.log(obj1);
obj1.age = 22;
console.log(obj, obj1);
输出结果:
第三种:for-in遍历实现深拷贝
let obj1 = {};
for (var attr in obj) {
obj1[attr] = obj[attr]
}
// console.log(obj1);
obj1.age = 33;
console.log(obj, obj1);
输出结果:
第四种:三个点语法
1、实现深拷贝
let obj1 = { ...obj };
obj1.name = '小番茄';
console.log(obj, obj1);
输出结果:
2、三个点实现数组的合并
let arr1 = [2, 3, 4];
let arr2 = [5, 6, 7];
let arr3 = [...arr1, ...arr2];
console.log(arr3);
输出结果:
3、实现对象的合并
let obj2 = { name: '小甜甜' };
let obj3 = { age: 18 };
let obj4 = { ...obj2, ...obj3 };
console.log(obj4);
输出结果:
4、函数参数的使用
传递的实参可以是一个数组
function fn(a, b, c) {
console.log(a, b, c);
}
let arr5 = [11, 22, 33];
fn(...arr5)
输出结果:
假如传递的参数是一个对象
function fn(name, age) {
console.log(name, age);
}
var obj = {
name: '小甜甜',
age: 18
}
fn(...obj)
输出结果:
其实是三个点语法不支持这种以对象的形式传递参数
5、将函数传递参数变成数组
输出结果是一个数组
function fn1(...arr) {
console.log(arr);
}
fn1('zs', 18)
输出结果: