javascript :了解浅层和深层复制(附实例)

71 阅读3分钟

浅层和深层拷贝介绍

有时,在应用程序中,我们必须为诸如数组/JSON/对象的重复拷贝等使用情况编写代码。本文包括对此的基本理解和例子。

Javascript为复制一个对象提供了两种类型
1.浅层拷贝
2.深度复制

javascript中的浅层复制

Shallow Copy example in javascript

它复制原始对象的一个值,并复制其他子对象的引用,如果其他子对象的引用。它复制像数字和字符串这样的基元,如果有任何子对象存在,新复制的对象有新的值作为子对象的引用。如果任何子对象被修改,它也会反映在原始和复制的对象中。在这种情况下,内存段是相同的,内存段的地址是一个点到单点。这将表现得很好,因为只有一个内存段的使用是非常少的。

让我们看看浅层拷贝的例子。这可以通过多种方式实现。

简单赋值

首先,创建一个雇员对象,名称为franc,部门为Marketing。

const originalEmployee = {  
  name: 'Franc',  
  department: {  
    type: 'Marketing'  
  }  
}  

下一步是通过赋值给一个新的变量来复制这个对象。

var copiedEmployee = originalEmployee;  

修改复制的对象,名称=Kiran,部门=Development

copiedEmployee.name = 'Kiran'  
copiedEmployee.department.type = 'Development'  
console.log('original', originalEmployee)  //returns {name:"Kiran", department:{type: "Development"}  
console.log('copy', copiedEmployee) //returns {name:"Kiran", department:{type: "Development"}  

现在,原来的雇员对象的原始值丢失了。原始和复制的对象已经指向了修改后的值。

使用Object.assign()方法

这也是只有值被复制,子引用被复制,但不是子对象本身。下面的代码对原始对象的修改与上面一样

const copiedEmployee = Object.assign({}, originalEmployee)  
originalEmployee.name = 'Kiran'  
originalEmployee.department.type = 'Development'  
console.log(originalEmployee) //returns {name:"Kiran", department:{type: "Development"}  
console.log(copiedEmployee) //returns {name:"Franc", department:{type: "Development"}  

创建一个原始对象并使用assign方法进行复制,现在我们修改了原始对象的值和对象的引用。被复制的对象没有修改的值仍然指向原始值,修改的对象引用值仍然指向原始和被复制对象的同一个对象。

使用Es6/Es2015扩展操作符

这是用最新的javascript浅层复制的另一种方法,这里有一个练习。

const copiedEmployee = { ...originalEmployee }  
originalEmployee.name = 'Kiran'  
originalEmployee.department.type = 'Development'  
console.log(originalEmployee) //returns {name:"Kiran", department:{type: "Development"}  
console.log(copiedEmployee) //returns {name:"Franc", department:{type: "Development"}  

其行为与object.assign()方法相同。

javascript中的深度复制

Deep Copy example in javascript

这是对原始对象的复制,它创建了一个新的内存段,并将新对象指向新创建的内存段。这里存在两个内存段,一个是原始对象,另一个是被复制的对象。它也复制了所有的值和参考对象的值。所以这里的两个对象是不同的对象。

使用实例

这可以通过创建新的对象变量和构建对象来实现,就像下面一样,我给出了上面相同的原始数据的例子

var duplicateCopy = { name: originalEmployee.name, department:{ type: originalEmployee.department.type } }; 

如果我们改变原有的雇员对象,复制的对象将不会被修改。两个对象是独立的。