900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > js深拷贝和浅拷贝对数组的影响_javascript之浅拷贝与深拷贝

js深拷贝和浅拷贝对数组的影响_javascript之浅拷贝与深拷贝

时间:2020-06-24 23:28:25

相关推荐

js深拷贝和浅拷贝对数组的影响_javascript之浅拷贝与深拷贝

好久没提笔写文章了,之前忙得喘不过气,过年回家也无心学习。年后回来后,调整好状态,准备把js基础重新过一遍。

正文从此开始:

之所以写这篇文章是因为Leader最近在面试,回来和我们数落了一通,问一个对前端深浅拷贝的问题,很多人都吱吱呜呜的囫囵吞枣,更有甚者说Object.assign()就是深拷贝的方法。问到能不能说说深拷贝方法的实现思路,也是说不出个所以然。不得不说,现在很多同学对js的基础这块还不够扎实呀,想着当初吃过这个问题的亏,就提笔写一篇文章,全权当巩固一下学过的知识,以后拿起来看的时候,也能心中有数。

Object.assign()

说起这个方法,其实它是个前拷贝的方法,自己去浏览器控制台验证一下就知道了

var test1 = {a: 1,b: 2,c: {d: 1,e: 2}}var test2 = Object.assign({}, test1)test1.a = 2test1.c.d = 2console.log(test2) // {a: 1, b: 2, c: { d: 2, e: 2 }}

解释一下,上面这串代码块把test1复制给了 test2,并且修改了 test1 的 a 属性和 c 属性的 d属性,最后输出的 test2 里 a 属性没变,但是 c 属性的 d 属性也跟着变了。

这是因为 Object.assign() 方法只是拷贝了第一层,而对于属性是一个对象的,就是引用其地址,所以 test1 和 test2 的 c 属性同时指向同一个地址,改变 test1 也会改变相应的 test2

同理ES6展开运算符...

也是一个浅拷贝,效果和 Object.assign() 是一样的

真正在代码业务中常用的深拷贝是JSON.parse(JSON.stringify(obj))

用代码去验证一下

var test1 = {a: 1,b: 2,c: {d: 1,e: 2}}var test2 = JSON.parse(JSON.stringify(test1))test1.c.d = 2console.log(test2) // {a:1, b:2, c: { d: 1, e: 2 }}

答案就是改变了 test1 的 c 属性的 d 属性,test2 没变,说明 test2 已经开辟了一个新的地址去存储 c 属性的指,两个变量互不影响。

但是事情并没有那么简单啊,这个方法的局限性还是有一些的,比如属性中存在正则运算符、undefined、不能序列化函数、不能解决循环引用的对象。

但是在项目中,JSON.parse(JSON.stringify(obj))这种方式已经是比较够用的,如果真的需要拷贝函数等其他属性的话,那就推荐去使用lodash的深拷贝方法吧,毕竟人家是专业的。

说到这那么就来一波常规操作,手撸一个简易版的深拷贝吧

// 判断是否是对象function isObj (o) {return ((typeof o === 'object') || (typeof o === 'function') && o !== null)}function deepClone (obj) {if (!isObj(obj)) {throw new Error '这不是一个对象'}let newObj = Array.isArray(obj) ? [] : {} // 判断是否是数组或者是对象 给一个空值Object.keys(obj).forEach(key => {newObj[key] = isObj(obj[key]) ? deepClone(obj[key]) : obj[key]}) // 循环存储return newObj}

当然这是相对较简单的深拷贝实现方式,更复杂的还需要考虑很多情况,在这不做深究。

希望对正在找新工作面试的同学有所帮助。有不对之处望不吝赐教。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。