通过项目实战学习:深拷贝与浅拷贝的内涵,实现深拷贝的几种方法,深拷贝解决项目异常bug

console.log(this.data[i]);

结果分析

===================================================================

我们只关注数组中的一个代表

举个例子,譬如未改动之前原表单的data和数据库的都是typescript。

第一次改动:

  1. 我在typescript后面加了个1,即表单的data变成typescript1

  2. 第一次点击cancel

  3. 输出结果如下:

console.log(this.data[i]); //typescript1;

console.log(this.dataFormDataBase[i]) //typescript

this.data[i] = this.dataFromDataBase[i];

console.log(this.data[i]); //typescript

  1. 说明第一次改动后cancel,数据库里的数据dataFromDataBase能够把原本的数据typescript还原给表单中的data,从而起到还原的作用

第二次改动:

  1. 我还是在原本表单输入框,在typescript后面加个1

  2. 第二次cancel

  3. 输出结果

console.log(this.data[i]); //typescript1;

console.log(this.dataFormDataBase[i]) //typescript1

this.data[i] = this.dataFromDataBase[i];

console.log(this.data[i]); //typescript1

??数据库里面的data也变成了typescript1???

为什么第一次dataFromDataBase没有问题,第二次就出现问题了

从此以后,不管怎么cancel,表单输入的值都会保存错误输入的值。

OMG

到这里,这么多疑惑,我们就得去了解一下深拷贝和浅拷贝的内涵了!

等了解了深拷贝和浅拷贝的区别原理,那就知道为什么会出现这样的bug。

再关注一下这一句关于赋值的代码,它在后面讲解是重点对象。

this.data[i] = this.dataFromDataBase[i];

深拷贝与浅拷贝

======================================================================

赋值操作


在了解深拷贝和浅拷贝之前,得先了解什么是拷贝copy。

其实在日常敲码的过程中,我们是经常在拷贝copy的。

这个拷贝,就是赋值操作。

赋值: 简单来说就是把某一数值或对象交给另外一个变量。

在JavaScript中,变量只是一个用于保存值的占位符

1.如果我们赋值赋的只是基本数据类型,那么变量只是保存了这个值。

2. 如果我们赋值的是引用数据类型,那么这个变量实际上保存的是该引用数据的地址。赋值,实际上是赋址

举个例子再理解一下赋值与“赋址”的区别:

一、基本数据类型:赋值后,两个变量互不影响

let a = ‘coffee’;

let b = a; //赋值

console.log(a); //coffee;

console.log(b); //coffee; 赋值成功

a = ‘milk’;

console.log(a); //milk

console.log(b); //coffee; 赋值后,变量a和变量b并没有关系

二、引用数据类型:赋值后,两个变量保存同一个地址,指向同一个对象,互相有影响。

let a = {

name:‘coffee’,

ice:‘less’

price:30

}

let b = a;

console.log(a);//{ name:‘coffee’,ice:‘less’,price:30};

console.log(b);//{ name:‘coffee’,ice:‘less’,price:30};

a.name = ‘milk’;

a.ice = ‘none’;

a.price = 8;

console.log(a);//{ name:‘milk’,ice:‘none’,price:8};

console.log(b);//{ name:‘milk’,ice:‘none’,price:8};

// 改变a,b也被改变了

// 因为实际上把a赋值给b,b就保存了a指向对象的地址,即a和b保存的是同一个对象的地址,他们都指向同一个对象,都引用了同一个对象。

破案:

到这里,其实我们已经能知道为什么会有上述的bug了:data和dataFromDataBase都是引用数据类型。在第一次cancel时,由于dataFromDataBase赋值给data,那么,data和dataFromDataBase则都引用了同一个对象;在第二次cancel时,当data发生变化,dataFromDataBase也就发生了变化!因为他们都指向同一个对象了。

那怎么办,我们就单纯地只想赋值呀。并不想这二者纠缠不清,表单的数据变了就影响到db的数据。

这时候就需要,深拷贝!进一步了解**什么是浅拷贝,什么是深拷贝!**最后的最后,知道怎么实现深拷贝,就可完结撒花了!

深拷贝的三种实现


深拷贝有什么用,开门见山:深拷贝之后,两个变量所引用的对象是两个毫无关系的对象,各过各的,互不影响

深拷贝会拷贝所有的属性,相当于浅拷贝来说时间长开销大。

噢~ ,那深拷贝正合我意,我就是想data和dataFromDataBase两个变量互不影响,我在赋值的时候实现深拷贝就好!

那怎么实现深拷贝?

总结一下实现深拷贝三种方法,具体如何使用可以上文档查看:

  1. JSON.stringify,JSON.parse : let b = JSON.parse(JSON.stringify(a));

  2. JQ的extend方法:let b = $.extend(true,[],a);

  3. lodash的cloneDeep方法:let b = cloneDeep(a);

深拷贝解决bug

这三种方法用哪一种都可以,我发现项目里这一part也有使用lodash的cloneDeep,所以,我也使用cloneDeep()

cancel(){

// change status after ‘cancel’ button clicked

// do something

// 遍历赋值 (关键点!!)

// 还原表单原本的值

for(let i = 0; i < this.data.length; i++){

this.data[i] = cloneDeep(this.dataFromDataBase[i]);

// 使用cloneDeep(),实现深拷贝。

}

// do something

刷面试题

刷题的重要性,不用多说。对于应届生或工作年限不长的人来说,刷面试题一方面能够尽可能地快速自己对某个技术点的理解,另一方面在面试时,有一定几率被问到相同或相似题,另外或多或少也能够为自己面试增加一些自信心,可见适当的刷题是很有必要的。

  • 前端字节跳动真题解析

  • 【269页】前端大厂面试题宝典

最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值