js 实现对象的拷贝、深拷贝
微wx笑
2021-01-13【前端开发】
3
0关键字:
js 对象 拷贝 深拷贝 复制 vue
在使用vue等响应式框架的时候,为了让框架能够监测到数据的改变,我们经常会用到对象的拷贝功能。这里收集了一些实现的方法及注意事项。Object.assign() 基本用法Object.assign
在使用vue等响应式框架的时候,为了让框架能够监测到数据的改变,我们经常会用到对象的拷贝功能。这里收集了一些实现的方法及注意事项。
Object.assign()
基本用法
Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}注意点
(1)浅拷贝
Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
const obj1 = {a: {b: 1}};
const obj2 = Object.assign({}, obj1);
obj1.a.b = 2;
obj2.a.b // 2上面代码中,源对象obj1的a属性的值是一个对象,Object.assign拷贝得到的是这个对象的引用。这个对象的任何变化,都会反映到目标对象上面。
方法一:利用JSON.stringify和JSON.parse
let swr = {
name:"邵威儒",
age:28,
pets:['小黄']
}
let swrcopy = JSON.parse(JSON.stringify(swr))
console.log(swrcopy) // { name: '邵威儒', age: 28, pets: [ '小黄' ] }
// 此时我们新增swr的属性
swr.pets.push('旺财')
console.log(swr) // { name: '邵威儒', age: 28, pets: [ '小黄', '旺财' ] }
// 但是swrcopy却不会受swr影响
console.log(swrcopy) // { name: '邵威儒', age: 28, pets: [ '小黄' ] }这种方式进行深拷贝,只针对json数据这样的键值对有效
对于函数等等反而无效,不好用,接着继续看方法二、三。
方法二
function deepCopy(fromObj,toObj) { // 深拷贝函数
// 容错
if(fromObj === null) return null // 当fromObj为null
if(fromObj instanceof RegExp) return new RegExp(fromObj) // 当fromObj为正则
if(fromObj instanceof Date) return new Date(fromObj) // 当fromObj为Date
toObj = toObj || {}
for(let key in fromObj){ // 遍历
if(typeof fromObj[key] !== 'object'){ // 是否为对象
toObj[key] = fromObj[key] // 如果为普通值,则直接赋值
}else{
if(fromObj[key] === null){
toObj[key] = null
}else{
toObj[key] = new fromObj[key].constructor // 如果为object,则new这个object指向的构造函数
deepCopy(fromObj[key],toObj[key]) // 递归
}
}
}
return toObj
}
let dog = {
name:"小白",
sex:"公",
firends:[
{
name:"小黄",
sex:"母"
}
]
}
let dogcopy = deepCopy(dog)
// 此时我们把dog的属性进行增加
dog.firends.push({name:"小红",sex:"母"})
console.log(dog) // { name: '小白',
sex: '公',
firends: [ { name: '小黄', sex: '母' }, { name: '小红', sex: '母' } ] }
// 当我们打印dogcopy,会发现dogcopy不会受dog的影响
console.log(dogcopy) // { name: '小白',
sex: '公',
firends: [ { name: '小黄', sex: '母' } ] }方法三
let dog = {
name:"小白",
sex:"公",
firends:[
{
name:"小黄",
sex:"母"
}
]
}
function deepCopy(obj) {
if(obj === null) return null
if(typeof obj !== 'object') return obj
if(obj instanceof RegExp) return new RegExp(obj)
if(obj instanceof Date) return new Date(obj)
let newObj = new obj.constructor
for(let key in obj){
newObj[key] = deepCopy(obj[key])
}
return newObj
}
let dogcopy = deepCopy(dog)
dog.firends.push({name:"小红",sex:"母"})
console.log(dogcopy)方法四
function deepClone(data){
var type = getType(data);
var obj;
if(type === 'array'){
obj = [];
} else if(type === 'object'){
obj = {};
} else {
//不再具有下一层次
return data;
}
if(type === 'array'){
for(var i = 0, len = data.length; i < len; i++){
obj.push(deepClone(data[i]));
}
} else if(type === 'object'){
for(var key in data){
obj[key] = deepClone(data[key]);
}
}
return obj;
}相关参考:
【ES6学习笔记之】Object.assign()
本文由 微wx笑 创作,采用 署名-非商业性使用-相同方式共享 4.0 许可协议,转载请附上原文出处链接及本声明。
原文链接:https://www.ivu4e.cn/blog/front/2021-01-13/604.html



