这是我参与新手入门的第2篇文章
前言
刚刚看了一篇关于如何实现深拷贝的文章,滑到下面看了眼评论,如下:
这让我联想到我在面试的时候也会问深拷贝有关的问题,下面就让我们来看看出题者的意图吧。
场景
在实际开发过程中因为浅拷贝的问题出了bug,功能需求是这样的:在地图上添加一个可拖拽的圆实现周边查询等功能。实现效果如下:
本文相关的主要问题出在计算拖拽按钮的坐标,拖拽圆鼠标事件功能不在此赘述。
开发设计思路
1、地图上选择一个点(中心点)
2、以这个点构建500米缓冲区(默认500米)
3、计算拖拽按钮坐标(x轴加500米)
4、拖拽时保持中心点不变,计算鼠标位置坐标距离中心点的距离
关键代码
坐标4326对应的单位为度,3857对应的是米,我们通常用的坐标都是经纬度,但是这边涉及增加500米以及距离计算需要以米为单位,因此涉及坐标转换
addDefaultCircle(x, y, param) {
//注意这里为何再定义两次
const center = new hmap.geom.Point(new hmap.basetype.Coordinate(x, y, 0));
//中心点
const point = new hmap.geom.Point(new hmap.basetype.Coordinate(x, y, 0));
//中心点转换坐标系并构建500米缓冲区
const circleGeo = point
.transform(this.map.getCrs(), 3857)
.getBuffer(param.distance);
//缓冲区面转为4326坐标系
const circleGeoTransform = circleVector.transform(3857, this.map.getCrs());
const polygonVector = new hmap.feature.Vector(circleGeoTransform, null);
let wktFeature = polygonVector;
this.dragCircleLayer.addFeatures([polygonVector]);
//拖拽按钮坐标系转为米
const pointBtn = point.transform(this.map.getCrs(), 3857);
//在x轴方向加500
pointBtn._coordinate._x = pointBtn._coordinate._x + 500;
//坐标系从米转为经纬度
const pointBtn1 = pointBtn.transform(3857, this.map.getCrs());
//此时第三个数据center为原始数据,point为添加了500后的数据
this.addDragBtn(pointBtn1, param.pic, center, param.drawCallBack);
//这么写会出bug 中心点会变为拖拽按钮的点位
// this.addDragBtn(pointBtn1, param.pic, point, param.drawCallBack);
}
结合知识点分析原因
以上代码涉及gis相关知识,可能理解起来会有些困难,但是被熏陶一次有助于理解下面代码,以下代码会更简洁的对比说明对象浅拷贝引起的问题
const a=1
const b=a+1
console.log(a) //a=1
console.log(b) // b=2
const point=new Point() //点对象 代表上述代码的中心点坐标
const pointBtn = point
pointBtn._coordinate._x + = 500; //拖拽按钮点坐标
//打印两个对象会发现point._coordinate._x和pointBtn._coordinate._x相同
console.log(point)
console.log(pointBtn)
通过对比可以发现中心点point的坐标被改变了,但是a不会改变。因此当对象或者数组有很多层级时浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型例如a,拷贝的就是基本类型的值,如果属性是引用类型如point,拷贝的就是内存地址 ,所以如果其中一个对象pointBtn改变了这个地址,就会影响到另一个对象point。
深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。
因此此处我们期望point是深拷贝
总结
以上就是我在开发过程中遇到有关深拷贝和浅拷贝的问题。它的实际应用场景不仅仅是面试,掌握它是可以帮助我们快速解决实际问题的。
关于如何实现深拷贝这类文章已经非常多,可以search一下,只要理解了概念和场景并代入理解,相信掌握和实现起来会更加深刻。