Javascript deeep copy
Javascript 深拷贝与浅拷贝
JavaScript是一种高级的,动态类型化脚本语言。像大多数其他编程语言一样,JavaScript允许支持深层拷贝和浅层拷贝的概念
浅拷贝:当参考变量被拷贝到使用赋值运算符一个新的参考变量,在创建时候是引用对象的浅表副本。简而言之,引用变量主要存储它引用的对象的地址。为新参考变量分配旧参考变量的值后,将存储在旧参考变量中的地址拷贝到新参考变量中。这意味着旧参考变量和新参考变量都指向内存中的同一对象。结果,如果对象的状态通过任何参考变量发生变化,则两者都会反映出来。让我们举个例子来更好地理解这些
举例说明
interface School {
student: string;
teacher: string;
address: string;
}
const middleschool: School = {
student: 'xiao',
teacher: 'mei',
address: 'china'
}
console.log('school origin:', middleschool);
let refmiddleschool = middleschool;
console.log('school origin:', refmiddleschool);
middleschool.student = 'ss';
console.log('school all changed:', middleschool);
console.log('school all changed:', refmiddleschool);
result
school origin: { student: 'xiao', teacher: 'mei', address: 'china' }
school origin: { student: 'xiao', teacher: 'mei', address: 'china' }
school all changed: { student: 'ss', teacher: 'mei', address: 'china' }
school all changed: { student: 'ss', teacher: 'mei', address: 'china' }
说明:从上面示例中可以看出,当middleschool.student名称被修改时,它也反映在refmiddleschool对象上,这可能会导致数据不一致。这称为浅拷贝。新创建的对象与旧对象具有相同的内存地址。因此,对它们中的任何一个所做的任何更改都会更改两者的属性。如果将其中一个从内存中删除,则另一个将不复存在。从某种意义上说,这两个对象是相互依存的。为克服此问题,可以使用深拷贝
深层拷贝:与浅层拷贝不同,深层拷贝会拷贝旧对象的所有成员,为新对象分配单独的内存位置,然后将拷贝的成员分配给新对象。这样,两个对象彼此独立,并且在对任何一个对象进行任何修改的情况下,另一个对象均不受影响。同样,如果删除了其中一个对象,则另一个仍保留在内存中。可以使用lodash提供的cloneDeep()方法做深拷贝,查看源代码可以看出是new了一个新对象
举个例子
import * as _ from 'lodash';
interface School {
student: string;
teacher: string;
address: string;
}
const middleschool: School = {
student: 'xiao',
teacher: 'mei',
address: 'china'
}
console.log('school origin:', middleschool);
const refmiddleschool = _.cloneDeep(middleschool);
console.log('school origin:', refmiddleschool);
middleschool.student = 'ss';
console.log('school all changed:', middleschool);
console.log('school all changed:', refmiddleschool);
执行结果
school origin: { student: 'xiao', teacher: 'mei', address: 'china' }
school origin: { student: 'xiao', teacher: 'mei', address: 'china' }
school all changed: { student: 'ss', teacher: 'mei', address: 'china' }
school all changed: { student: 'xiao', teacher: 'mei', address: 'china' }
说明:修改后,两个对象具有不同的属性。同样,每个对象的方法定义不同,并产生不同的输出
参考文档
[1] geeksforgeeks [2] Lodash