如何实现一个完美的深拷贝库? |
您所在的位置:网站首页 › js引用类型和值类型的区别 › 如何实现一个完美的深拷贝库? |
👆点击“博文视点Broadview”,获取更多书讯 lodash里的cloneDeep函数可以用来解决深拷贝的场景,但你有没有思考过lodash里的cloneDeep函数是如何实现的呢? 虽然我们可以直接使用lodash,但是学习深拷贝函数的实现原理仍然是非常有意义的,深拷贝也是一道非常经典的前端面试题,其可以考察面试者的很多方面,比如基本功、代码能力、逻辑能力。 深拷贝看似简单,但要想实现一个完美的深拷贝却并不容易,通过笔者的面试考察经验来看 ,只有 50%的人能够实现基础版本,能实现完美版本的竟然不到1%,这是因为深拷贝存在很多坑,比如: 你知道使用JSON.stringify来实现深拷贝是有bug的吗?你会使用循环实现深拷贝吗?如果拷贝的对象存在循环引用该怎么破解?如果你回答不上来上面的问题,那么继续往下阅读吧,本文将破解深拷贝的谜题,由浅入深,环环相扣,总共涉及4种深拷贝方式,每种方式都有自己的特点和个性。 深拷贝 VS 浅拷贝开始之前先科普一下什么是深拷贝,和深拷贝有关系的另一个术语——浅拷贝又是什么意思呢? 其实深拷贝和浅拷贝都是针对引用类型来说的,JS中的变量类型分为值类型(基本类型)和引用类型;对值类型进行复制操作会对值进行一份拷贝,而对引用类型赋值,则会进行地址的拷贝,最终两个变量指向同一份数据。示例代码如下。 // 引用类型指向同一份数据 var a = {c: 1}; var b = a; a.c = 2; console.log(a.c, b.c); // 2, 2 全是2,a b指向同一份数据引用类型会导致a和b指向同一份数据,此时如果对其中一个进行修改,就会影响到另外一个,有时这可能不是我们想要的结果,如果对这种现象不清楚的话,还可能造成不必要的bug。 最简单的深拷贝深拷贝的问题其实可以分解成两个问题:浅拷贝+递归。什么意思呢?假设我们有如下数据: var a1 = {b: {c: {d: 1}};使用递归实现深拷贝的示例代码如下: function clone(source) { var target = {}; for(var i in source) { if (source.hasOwnProperty(i)) { if (typeof source[i] === 'object') { target[i] = clone(source[i]); // 注意这里 } else { target[i] = source[i]; } } } return target; }大部分人都能写出上面的代码,但如果问上面的代码有什么问题的话,就很少有人答得上来了。聪明的你能找到问题吗? 其实上面的代码问题太多了,比如: 没有对参数做检验判断是否对象的逻辑不够严谨没有考虑数组的兼容其实这三个都是小问题,递归方法最大的问题在于爆栈,当数据的层次很深时就会栈溢出。 下面的代码可以生成指定深度和每层广度的代码,这段代码我们后面还会再次用到。 function createData(deep, breadth) { var data = {}; var temp = data; for (var i = 0; i |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |