推荐配套阅读文章:
www.jianshu.com/p/2188dcd91… www.freecodecamp.org/news/copyin…
为什么要学习深拷贝和浅拷贝?
以下是我在学习工作中的一些实践心得,如果你阅读起来感到困惑或者信息重复,可以略过不看。旨在为大家提供一个思考支线。我在实际情况中,遇到需要用到深拷贝和浅拷贝的情况是:需要Functional Programming遵循不变性原则来编程的时候。
FP是另一个非常庞杂的体系,如果使用过redux的小伙伴应该不会陌生,这里面不做展开,只稍微带一下不变性原则做一个背景说明:
- 不变性原则:是指你不能随意概念变量的值,如果你要概念它先复制然后再操作
let numbers = [1,2,3]; function addOne(array){ let arr = array.slice();//先复制再操作,不影响外面的numbers return arr.map(item=>item+1); } addOne(numbers);我当时还没有接触到FP的时候,看到很多看起来很高级的代码都会有个slice啥的,一直不知道为什么要这么做。根据不变性的原则,这样做的目的是为了保证函数完全的独立性,不对外产生任何影响,这样再组装拼接功能的时候就不会担心存在副作用了,我称为乐高化的过程。
思维导图
概念分析
什么是深拷贝什么是浅拷贝?
深浅拷贝面向的对象是reference type的数据类型,即数组和对象。因为在JS里面数组和对象的“=”,是指向了同一个参考地址(浅拷贝),而在实际的编码需求中(比如FP不变性),我需要完成基本数据类型的拷贝,即开辟不同的存储地址,但地址中的value要一摸一样(深拷贝)。
谈一谈深拷贝的解决方案:
- 是否需要掌握自己写原生深拷贝?
我认为是不需要的,但看你的需求,看原生代码并自己实现的重要意义,我认为是真切的明白原理。 比如知道底层的原理不过就是:
recursion而已。在现实编码中已经有很多非常成熟的库可以应用比如react里面的immutatable.js。
- 我常用的深拷贝方法
- 数组
let numbers = [1,2,3]; let array1 = numbers.slice();//ES5,旧爱 let array2 = [...array1];//ES6,新欢
- 对象
let obj = {x:1,y:2}; let obj1 = obj.assign({},obj);//ES5,旧爱 let obj2 = {...obj};//ES6,新欢
- 深拷贝失效以及我如何解决这种失效
- 对象
let obj = {x:1,y:{z:2}};//高维对象第二点提供的方法里会失效 let obj1 = JSON.parse(JSON.stringify(obj));//stringify //经常使用immer.js import {produce} from "immer"; let obj2 = produce(obj,objscratch=>{});
- 怎样看待深拷贝失效?
深拷贝失效多出现在处理http传来的json object时,一般这种项目大多情况会使用稳定的类库lodash,immer来提高开发效率。自己设计的小型项目,根据数据类型不同使用轻量级的操作符
spread operatorassignstringifyslice多可以解决。不用太担心深拷贝失效的问题,已经有非常多成熟的方法解决它,关键明白这个bug的成因,提高debug的效率才是真。