js中的赋值、浅拷贝和深拷贝的使用,理解其区别所在

什么是数据类型?

首先数据分为基本数据类型引用数据类型。而今天要说明的就是对引用数据类型的数据(对象)进行赋值、浅拷贝和深拷贝后,如果修改新对象的属性值,源对象中会发生什么变化。

二、赋值、浅拷贝和深拷贝

浅拷贝: 创建一个新对象,拷贝源对象的属性值。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。注意:当object只有一层的时候,是深拷贝

深拷贝: 创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”。

赋值:指引用地址的拷贝。要修改赋值后的数据时,如果是引用数据类型,则会影响到原数据。

先上一个简单的示例吧,这个是用到一些基础的vue2写的一个crud,实现对列表里学生的添加,修改,删除和查询功能,其中就涉及到了引用地址的知识。

 当点击编辑的时候会隐藏当前div,显示编辑部分的div

 而容易出现问题的地方就是这里,因为代码中编辑按钮与学生对象进行了双向绑定,所以容易出现点击取消值仍然被修改的情况,当然也有其他写法可以避免此情况,但今天遇到了就分享一下吧~

1.先上代码,看一下这里是编辑按钮部分,一个点击事件,传入一个stu对象

 <!-- 查 -->
            <tr v-for="stu in students">
                <td>{{stu.name}}</td>
                <td>{{stu.weight}}</td>
                <td>
                    <button type="button" @click="editStu(stu)">编辑</button>
                    <button type="button" @click="deleteStu(stu.name)">删除</button>
                </td>
            <tr>

2.编辑部分div代码,绑定了data里面的studentUpdate对象中的属性值,也是一会要用到的对象,下面还有两个单击事件

<!-- 编辑页面 -->
    <div v-if="showUpdateView">
        姓名:
        <!-- 双向绑定到data里 -->
        <input type="text" v-model="studentUpdate.name" disabled="disabled">
        <br>
        体重:
        <input type="number" v-model="studentUpdate.weight">
        <br>
        <button type="button" @click="update">修改</button>
        <button type="button" @click="cancel">取消</button>
    </div>
</div>

3.重要的来了,edit方法,这里就用到了Object的assign方法,也就是浅拷贝!

 //点击编辑页面效果
            editStu(stu) {
   
                this.studentUpdate = Object.assign({}, stu);
                console.log(this.studentUpdate == stu); //这里false,也就是说引用不是同一个地址
                console.log(stu); //可以看到源对象的值并无变化
                this.showUpdateView = true;
            }

这里可以看到复制后,如果stu对象的某属性不只一层,拷贝的是对象的该属性的引用,而不是对象本身;但因为这里stu对象只有一层,所以这两个属性成了深拷贝,就是拷贝的知识属性的值!所以studentUpdate对象与stu对象进行==内存地址比较,结果为false,也就是说两个对象并没指向同一个内存地址。而且当在输入框中写了新值,打印后结果并无变化,stu的属性值不受studentUpdate对象修改的影响。

4.再来看一下update方法,第一行将students数组对象中过滤出与当前要修改的student对象名字相同的对象的引用地址直接赋值给了student,也就是说此时如果更改属性值,直接影响到源对象的属性值了!

第二行再次用到浅拷贝,将编辑后的对象覆盖到student对象,也就是数组中源对象的属性值,浅拷贝中如果目标对象已经存在相同的属性,则会进行覆盖!

此时点击修改按钮就会修改传入对象stu的属性值!点取消就会正常显示原本的值,且不点修改,原本的值就不会发生变化!

  update() {

                let student = this.students.filter(o => o.name === this.studentUpdate.name)[0];
                Object.assign(student, this.studentUpdate);
                this.showUpdateView = false;
            }

继续加油 !

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值