js的两大数据类型:
- 简单类型值:数值(Number)、字符串(String)、布尔值(Boolean)、null、undefined
- 引用类型值:函数、数组
对象克隆的使用场景
1.将对象作为函数参数的时候,不希望操作原对象
2.面试常见问题
克隆的定义:
在js中对象克隆就是把对象值重新赋给一个新对象,克隆分为深克隆和浅克隆。
浅克隆
浅克隆:只是复制对象的第一级属性值,如果对象的第一级属性中包含引用类型,则只复制地址。
简单数据类型浅克隆:
//数值
let num = 10;
let num1 = num;
num = 20;
console.log(num); //20
console.log(num1); // 10
//字符串
let str = "hello";
let str1 = str;
str = "world";
console.log(str); //world
console.log(str1); // hello
引用类型的浅克隆(错误示例):
//错误示范
const stu = {
name:"张三",
age:15,
}
const stu1 = stu;
stu.name = "李四"
console.log(stu); //李四
console.log(stu1); //李四
为什么不行了呢?
引用类型的值都会被保存在堆内存中,在栈内存中会存在一个指针指向堆内存中的值。两个对象都指向一个地址,所以当地址一但改变,两个指向同一个地址所以都会改变
接下来了解一下for in语句
for in 语句
语句用于循环对象属性。
循环中的代码每执行一次,就会对数组的元素或者对象的属性进行一次操作
let stu = {
name:"yhl",
age:18
}
for(let a in stu){
console.log(a);// 可以获取到stu对象的属性
console.log(stu[a]); //可以获取到属性值
}
引用数据类型:第一种:使用 for in 语句进行对象的浅克隆
// 浅拷贝
let stu = {
name:"张三",
age:18
}
function copyObj(obj){
let newObj = {};
for(let i in obj){
newObj[i] = obj[i]
};
return newObj;
};
let stu2 = copyObj(stu);
stu.age = 20;
console.log(stu); // {name:"张三",age:20}
console.log(stu2); // {name:"张三",age:18}
第二种: 使用es6扩展运运算符
const stu = {
name:"张三",
age:18
}
const stu1 = {...stu};
stu.name = "李四"
console.log(stu); // {name: '李四', age: 18}
console.log(stu1);// {name: '张三', age: 18}
如果一个对象里面又嵌套一个对象呢?
// 如果张三有个同学叫李四
const stu = {
name: "张三",
age: 19,
bestfriend: {
name: "李四",
age: 20
}
}
function fun(stu) {
let newStu = {};
for (let i in stu) {
newStu[i] = stu[i]
}
return newStu;
}
let newStu = fun(stu)
stu.bestfriend.name = "王五"
console.log(stu);
console.log(newStu);
发现两种方法都会是对象里面的引用类型李四变成了王五,说明了浅克隆只会复制第一级属性,如果是包含了引用类型,就只复制地址。如果属性还有引用类型的话,就要使用深克隆了。
深克隆:
所有属性都会克隆,就算有引用地址也会进行克隆
第一种: JSON.parse和 JSON.stringify()实现克隆
const stu = {
name: "张三",
age: 19,
bestfriend: {
name: "李四",
age: 20
}
};
let a = JSON.stringify(stu);
console.log(a);
let stu2 = JSON.parse(a);
stu.bestfriend.name = "王五"
console.log(stu);
console.log(stu2);
运行结果:
第二种:递归调用
const stu = {
name: "张三",
age: 19,
bestfriend: {
name: "李四",
age: 20
}
};
function fun(stu) {
// 创建一个新对象
let newStu = {};
for (let i in stu) {
// 克隆
if (stu[i] instanceof Object) {
newStu[i] = fun(stu[i])
} else {
newStu[i] = stu[i]
}
}
return newStu;
}
let newStu = fun(stu)
stu.bestfriend.name = "王五"
console.log(stu);
console.log(newStu);
//运行结果和上图一样
深克隆和浅克隆的区别
浅度克隆:原始类型为值传递,对象类型仍为引用传递。其本质上并没有成为一个单独的个体与原对象脱离。
深度克隆:所有元素或属性均完全复制,与原对象完全脱离,也就是说所有对于新对象的修改都不会反映到原对象中。
以上就是我对深、浅克隆的理解,有理解不到位的地方欢迎大家指正!