1.问题来源
js中存储分为基本数据类型和引用数据类型,其区别为:
基本数据类型存在栈中,存取直接调取即可
引用数据类型存在堆中,其指针存在于栈中,存取时通过查找栈的地址,将数据存储或查询.
所以当赋值时,基本数据类型增加栈,而引用数据类型,复制的是堆的指针,即增加的也是栈,所以造成一些奇怪的现象
2.赋值
基本数据类型无影响,引用数据类型修改混乱
//基本数据类型赋值
let count = 1 //栈入1
let test = count //栈入1
test = 2 //修改栈中数据
console.log(count); //1
console.log(test) //2
//引用数据类型赋值
const obj = { name: '小明', age: 18 } //数据存入堆中(假设a堆) ,指针存入栈中(假设b指针)
let test = obj //复制obj的指针(b)
test.name = '小红' //修改指针(b)的对应堆(a)的数据
console.log(obj); // 查找指针(b)对应的堆(a) {name: '小红', age: 18}
console.log(test); // 查找指针(b)对应的堆(a) {name: '小红', age: 18}
3.浅拷贝
浅拷贝的含义为只复制最外层,如果第一层是 基本数据类型,则新建栈存入数据,如果第一层是引用数据类型,则新建栈存入其指针
//定义引用类型的对象obj
const obj = {name: 'Jack', address: { city: '北京'}}
//定义需要浅拷贝的对象test
const test: any = {}
// 遍历浅拷贝
for (let k in obj) { test[k] = obj[k] } //直接复制每一项
console.log(obj) // {name: 'Jack', address: { city: '北京' }}
console.log(test) // {name: 'Jack', address: { city: '北京' }}
test.name="小明" //浅拷贝第一层存堆
console.log(obj) // {name: 'Jack', address: { city: '北京' }}
console.log(test) // {name: '小明', address: { city: '北京' }}
test.address.city="上海" //浅拷贝更深层存指针
console.log(obj) // {name: 'Jack', address: { city: '上海' }}
console.log(test) // {name: '小明', address: { city: '上海' }}
4.深拷贝
深拷贝含义为重新开辟出一块堆,把原来引用类型的所有数据,复制到新开辟的堆中
//定义引用类型的对象obj
const obj = {
name: 'Jack',
age: 18,
info: {
height: 180,
weight: 180,
desc: {
message: '今天天气很好'
}
},
address: {
city: '北京'
},
hobby: ['吃饭', '睡觉']
}
//定义需要深拷贝的对象test
const test: any = {}
// 递归
const deepCopy = (test: any, obj: any) => {
for (let k in obj) {
//如果第k项是对象,则继续遍历
if (Object.prototype.toString.call(obj[k]) === `[object,Object]`) {
//定义test中第k项为对象,继续递归
test[k] = {}
deepCopy(obj[k], test[k])
}
//如果第k项为数组,则定义数组继续递归
else if (Object.prototype.toString.call(obj[k]) === `[object,Array]`) {
test[k] = []
deepCopy(obj[k], test[k])
}
//如果第k项为基本数据类型,直接复制
else {
test[k] = obj[k]
}
}
}
//此时修改test或obj中的任何值,都不会影响对方的数据