layout: post
title: 对象(数组)的拷贝
date: 2017-08-31 16:10:17
tags: 学习
老生常谈
都是很老的问题了,为啥还要写,网上搜索一大堆。其实是有个小故事的,第一次面试的时候,面试官就给我出了一个拷贝的题,奈何我当时还是小白。。。什么都不懂,现在过了接近一年,刚好看到相关的东西,就顺道总结一下。
what is clone
对象拷贝(也叫复制),得到一个与已知对象看起来"相同的对象",但是本质上不是一个对象,也不是同一个引用。如果只复制一层,就叫浅复制,对象经常是多层,多层的就是深复制。
浅拷贝(shallow clone)
第一时间想到的就是遍历
const shallowClone = (current) => {
let obj = {}
for(let i in current){
if(src.hasOwnProperty(i)){ // 只遍历本身的属性
obj[i] = current[i]
}
}
return obj
}
let cur = {a:1,b:2}
console.log(shallowClone(cur))
深拷贝(deep clone)
网上大牛写的挺多的,序列化啥的。不考虑特殊情况,递归遍历应该是基本可以满足要求的,但是仅仅是基础实现,涉及到原型链上的方法之类的,暂时不作讨论。
let cur = {a:1,b:{c:2,d:{e:3}},c:function(){return 1+2 }}
const deepClone = (current) => {
let obj = {}
for(let i in current){
if(current.hasOwnProperty(i)){
obj[i] = typeof(current[i]) === 'object' ? deepClone(current[i]) : current[i]
}
}
return obj
}
console.log(deepClone(cur))
还有大家公认的方法啦,弊端就是没有方法,null,undefined这些了。
Json的方法
let obj = {a:1,b:{c:2,d:{e:3}},c:function(){return 1+2 }}
let target = Json.parse(Json.stringfy(obj))
target // {a:1,b:{c:2,d:{e:3}}} copy不了里面的方法
数组的clone
比较简单的就是split(0) 和 concat() 了,这2个方法都是没有side effects。
其他遍历的方法应该也是ok的,但是深clone可能会比较烦啦 ~~~~