js中的赋值,深拷贝和浅拷贝

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中的任何值,都不会影响对方的数据

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值