首先我们需要掌握一些基本的知识点:
1、在JS中,数据类型分为:
基本数据类型:Number,String,Undefined,Null,Boolean,Symbol,BigInt
引用数据类型:(object) 分为 👉👉Array, function, date, RegExp
2、JS中,栈(stack)和 堆(heap):
栈(stack)为自动分配的内存空间,它由系统自动释放。
堆(heap)为动态分配内存空间,大小不定,不会自动释放。
栈里存放:基本类型全部和引用类型的名字
堆里存放:引用类型的值
目录
1. 基本数据类型:赋值,赋值之后两个变量互不影响。非同一地址值
2. 引用数据类型:赋值,两个变量具有相同的地址值,相互之间有影响。同一地址值
使用 assign 方法创建对象 (assign之前学过用来做对象的合并)
三:深拷贝 就是 开辟属于自己的新地址,逐个将原数据的属性添加到新地址内。修改新数据不影响旧数据(都不是同一地址值)
1.首先JSON.stringify(JS对象) 将 JS 旧对象转化为 JSON 格式的字符串
2.然后JSON.parse(字符串名) 将 JSON 格式的字符串转化为 JS 新对象,用新变量接收
一: 直接赋值
1. 基本数据类型:赋值,赋值之后两个变量互不影响。非同一地址值
let a = 10;
let b = a;
b = 100;
console.log(a) //10
console.log(b) //100
2. 引用数据类型:赋值,两个变量具有相同的地址值,相互之间有影响。同一地址值
let x = [1, 2, 3, 4, 5]
let y = x
y[0] = 666
console.log(x) //[666,2,3,4,5]
console.log(y) //[666,2,3,4,5]
let a = [1, { name: '与世无争' }, 3, 4];
let newA = a;
a[0] = 666 //一级属性
a[1].name = '大富大贵'; //二级属性
console.log(a); //[666,{name:'大富大贵'}, 3, 4]
console.log(newA); //[666,{name:'大富大贵'}, 3, 4]
浅拷贝:新数据与旧数据共享一块内存
深拷贝:自己开辟一个新内存,
二:浅拷贝:只拷贝第一层(只有第一层不是同一地址值)
1:数组浅拷贝的方法
-
① 用数组的concat方法 : 基本拷值,引用拷地址值
-
② 用数组的slice方法 : 基本拷值,引用拷地址值
-
③ 扩展运算符...
let a = [1,{name:'羊'},[0,0,0,]]
let b = a.slice(0)
// let b = [].concat(a)
// let b = [...a]
a[0] = 10
a[1].name = '杨'
a[2][0] = 3
console.log(a) // [ 10, {name:'杨'}, [3, 0, 0] ]
console.log(b) // [ 1, {name:'杨'}, [3, 0, 0] ]
2. 对象浅拷贝的方法
使用 assign 方法创建对象 (assign之前学过用来做对象的合并)
//使用 assign 方法创建对象 (assign之前学过用来做对象的合并)
const school = {
name: "尚硅谷",
pos: ['北京', '上海', '深圳']
}
const newSchool = Object.assign({}, school);
newSchool.name = 'atguigu'; //基本类型原数组不变
newSchool.pos[0] = 'beijing'; //引用类型原素组改变
console.log(school); //{name:'尚硅谷',post:['beijing','上海','深圳']}
console.log(newSchool);{name:'atguigu',post:['beijing','上海','深圳']}
三:深拷贝 就是 开辟属于自己的新地址,逐个将原数据的属性添加到新地址内。修改新数据不影响旧数据(都不是同一地址值)
实现方法 :JSON实现深拷贝,缺陷: 不能复制方法
1.首先JSON.stringify(JS对象) 将 JS 旧对象转化为 JSON 格式的字符串
2.然后JSON.parse(字符串名) 将 JSON 格式的字符串转化为 JS 新对象,用新变量接收
此时新变量就是深拷贝,地址值不一样了
let school = {
name: '尚硅谷',
pos: ['北京', '上海', '深圳'],
founder: {
name: '刚哥'
},
change: function () {
console.log('改变');
}
}
//将 JS对象 转为 JSON 格式的 字符串
let str = JSON.stringify(school);
console.log(str); //{"name":"尚硅谷","pos":["北京","上海","深圳"],"founder":{"name":"刚哥"}}
console.log(typeof str); //string
//将 JSON对象 转为 JS对象
let newSchool = JSON.parse(str);
console.log(newSchool); //{name: "尚硅谷", pos: Array(3), founder: {…}}
//测试深拷贝
newSchool.name = '嘿嘿嘿'
newSchool.pos[0] = 'beijing';
console.log(school); //{"name":"尚硅谷","pos":["北京","上海","深圳"],"founder":{"name":"刚哥"},change: ƒ}
console.log(newSchool); //{"name":"嘿嘿嘿","pos":["beijing","上海","深圳"],"founder":{"name":"刚哥"}}
四: 用递归实现深拷贝
1.fn方法:判断 a 的类型,如果是基本数据类型 直接return值,如果是引用数据类型 进入 skb方法
2.skb方法:开辟新值: a是数组给[];是对象给{}
3.遍历a内部值,如果是基本数据类型,新值直接添加此值
如果是引用类型,重复2的操作
<script>
let a = {
name:'yy',
arr:[10,{name:'数组',age:'18'}],
}
let b = fn(a)
function fn(a){
if(typeof a ==="object" && a !== null){
return skb(a)
}else{
return a
}
}
function skb(old){
var container = Array.isArray(old)?[]:{}
for(let i in old){
if(typeof old[i] === "object" && old[i] !== null){
container[i] = skb(old[i]) // skb(arr:[10,{name:'数组',age:'18'}])
}else{
container[i] = old[i]
}
}
return container
}
b.name = '嘿嘿'
b.arr[1].name = '嘿嘿'
console.log(a)
console.log(b)
</script>