Welcome to The JS Bifrost, your pathway to rock solid foundation for a God-level JavaScript. This is the third article in the series which talks about #objects #javascript #shallowCopy #deepCopy
欢迎来到JS Bifrost,这是您为上帝级JavaScript奠定坚实基础的途径。 这是该系列的第三篇文章,讨论#objects #javascript #shallowCopy #deepCopy
![Image for post](https://miro.medium.com/max/9999/1*C3vgrvmRSoPu1_-5UP6Omw.png)
Before going forward, let us understand Objects and references in JavaScript.
在继续之前,让我们了解JavaScript中的对象和引用。
What is an Object??
什么是对象?
Object is a container of properties associated as key and value pairs. The values in an Object can be functions that are commonly referred to as methods.
对象是作为键和值对关联的属性的容器。 对象中的值可以是通常称为方法的函数。
Object is created only once in JavaScript, and we can refer Object by creating a reference to Object.
对象在JavaScript中仅创建一次,我们可以通过创建对对象的引用来引用对象。
What is Reference??
什么是参考??
Reference is nothing but the variable which refers to a memory location where a created Object is stored.
引用不过是变量,它指向存储创建的对象的存储位置。
Example :
范例 :
let student = {roll_no: 10,name: “Anna”}
We can refer above Object by using student
reference. So we can say student
is a reference which refers the Object { roll_no:10, name: “Anna” }.
我们可以使用student
参考资料来引用上述对象。 因此,可以说student
是引用对象{roll_no:10,name:“ Anna”}的引用 。
Now, we know how to deal with Object and reference in JavaScript, let us see how to copy data to and from Object.
现在,我们知道了如何使用JavaScript处理对象和引用,让我们看看如何在对象之间复制数据。
There are 2 methods of copying data from Object
有两种从对象复制数据的方法
1. Shallow Copy
1.浅拷贝
2. Deep Copy
2.深拷贝
You might think that copying data simply means creating a replica of existing data, that’s it !!!
您可能会认为复制数据只是意味着创建现有数据的副本,仅此而已!!!
But NAY :( there’s a lot more to it.So what is it ???Shallow Copy? Deep Copy?
但是NAY :(还有很多东西。那么它是什么?
![What is Shallow copy and Deep copy](https://miro.medium.com/freeze/max/9999/1*GdrE1jFZpBhd1ZiyLGaRRg.gif)
浅拷贝与深拷贝 (Shallow Copy VS Deep Copy)
In a below diagram, you can see clear difference between shallow copy and deep copy.
在下图中,您可以看到浅拷贝和深拷贝之间的明显区别。
![Image for post](https://miro.medium.com/max/9999/1*hRzn0dYrUhkRT0vLFTYUxw.png)
In shallow copy, the original Object and cloned Object point to the same referenced Object or same memory location. Comparatively, in deep copy, original Object and cloned Object point to different memory locations.
在浅表复制中 , 原始对象和克隆的对象指向相同的引用对象或相同的内存位置。 相比之下,在深层复制中 , 原始对象和克隆的对象指向不同的内存位置。
![Image for post](https://miro.medium.com/max/9999/1*Bi-CMivmhqY3IAvvGDGobg.png)
In the above picture, we can see actual memory allocation for the original and cloned Object. Let’s consider p is the original Object and q is the cloned reference.
在上图中,我们可以看到原始对象和克隆对象的实际内存分配。 让我们考虑p是原始Object,q是克隆的引用。
In shallow copy, original Object (p) and copied reference (q) are pointing to the same memory location(100). That’s why both references will modify the same data.
在浅表复制中, 原始对象 ( p)和复制的引用 ( q)指向相同的存储位置(100) 。 这就是两个引用都将修改相同数据的原因。
In a deep copy, data of the original Object(p which is at 100 memory location) gets copied into cloned reference(q) with a separate memory location(101). Another new reference gets created in memory(that is q). Modification of any Object data won’t affect one another.
在深层副本中 , 原始Object(p位于100个存储位置)的数据将被复制到具有单独 存储位置(101)的 克隆参考 ( q )中 。 在内存中创建另一个新引用( 即q) 。 修改任何对象数据不会互相影响。
Whatever we saw until now was just the tip of the iceberg. Let's dig into each one of them deeper.
到目前为止,我们所看到的只是冰山一角。 让我们更深入地研究它们中的每一个。
浅拷贝 (Shallow Copy)
In Shallow Copy, original reference and copied reference points to the same memory location. Changes on copied reference reflect on the original reference and vice versa.
在“浅复制”中, 原始参考和复制的 参考指向相同的存储位置。 复制参考的更改反映在原始参考上 ,反之亦然。
For any given Object, the first level of properties gets copied and the deeper(nested) level of properties gets referenced.
对于任何给定对象,将复制属性的第一级,并引用属性的更深(嵌套)级。
Let us see how to implement a shallow copy.
让我们看看如何实现浅表副本。
There are multiple ways to implement a shallow copy, let us see one using the spread operator.
实现浅表副本的方法有多种,让我们看看使用散布运算符的一种。
Using Spread(…) Operator
使用Spread(…)运算符
The Spread operator is used to make a copy of an existing Object — the ES6 way of a shallow copy.
Spread运算符用于创建现有对象的副本-浅表副本的ES6方式。
Example
例
![Example of Spread Operator](https://miro.medium.com/max/9999/1*py8Wtj5e-9ZbP9SnV3fypQ.png)
In the above snapshot, the student is pointing to the original Object and newStudent is a new reference.
在上面的快照中,学生指向原始对象,而newStudent是新引用。
newStudent = { ...student }
The above statement copies all values from student and nested Object references. Now, newStudent.address will point to same memory location where student.address is pointing and same copy of other variables created.
上面的语句复制了来自Student和嵌套Object 引用的所有值。 现在, newStudent.address将指向student.address指向的相同内存位置,并创建其他变量的相同副本。
When we modify the data of newStudent.address variable, then the original student.address will get modified.
当我们修改newStudent.address变量的数据时,原始的student.address将被修改。
Object.assign() is also used to achieve shallow copy.
Object.assign()也用于实现浅表复制。
深拷贝 (Deep Copy)
In Deep Copy, an exact replica of the original Object is created in memory with new reference. So modifications on one Object doesn’t affect its copied Object and vice versa.
在Deep Copy中,将使用新的reference在内存中创建原始对象的精确副本。 因此,对一个对象的修改不会影响其复制的对象,反之亦然。
Copied references get disconnected from original references.
复制的参考与原始参考断开连接。
Let us see how to implement a deep copy.
让我们看看如何实现深层复制。
Using JSON.parse() and JSON.stringify() methods
使用JSON.parse()和JSON.stringify()方法
A very simple and efficient way of doing deep copy is JSON.parse(JSON.stringify(object)).
进行深度复制的一种非常简单有效的方法是JSON.parse(JSON.stringify(object))。
Example
例
![Deep copy Example](https://miro.medium.com/max/9999/1*-X2iMoB9etp52LC3d7EKLg.png)
In the above example, newStudent is the copy of student reference, but they are placed at different locations in memory. That’s why when we are modifying any reference, it won’t affect the other one.
在上面的示例中, newStudent是学生参考的副本,但它们位于内存中的不同位置。 这就是为什么当我们修改任何引用时,它不会影响另一个引用。
_.cloneDeep() is also used for deep copy. For this, we need to import lodash library or specific function.
_.cloneDeep() 也用于深层复制。 为此,我们需要导入 lodash 库或特定功能。
As of now, we have seen What is shallow copy and deep copy, How it works, and it’s implementation.
到目前为止,我们已经了解了什么是浅表副本和深表副本,它是如何工作的以及它的实现。
Still, confused between Shallow copy and Deep copy??
尽管如此,在浅拷贝和深拷贝之间还是感到困惑?
No worries…
别担心…
Let us see a simple real-life example related to shallow copy and deep copy.
让我们看一个与浅拷贝和深拷贝有关的简单的实际示例。
For simple understanding, we can keep in mind that Shallow copy is looking ourselves in the mirror(you are Object and replica in mirror can be a reference).
为了简单理解,我们可以记住,浅拷贝是在镜像中寻找自己(您是Object,镜像中的副本可以作为参考)。
![Image for post](https://miro.medium.com/max/9999/1*-DKgUdzke2iuFPRL61nX-Q.jpeg)
Consider twin brothers/sisters. They are a perfect example of Deep Copy. Twins are copies of each other but they are different in real life as original and copied Objects in memory😀.
考虑双胞胎兄弟姐妹。 它们是Deep Copy的完美示例。 双胞胎是彼此的副本,但在现实生活中它们与内存中的原始对象和复制的对象不同。
![Image for post](https://miro.medium.com/max/9999/1*IwqA2H0cZfEsYgoNZq_zEQ.jpeg)
Now,let's summarise what we learnt till now…
现在,让我们总结一下到目前为止我们学到的东西...
![Image for post](https://miro.medium.com/max/9999/1*PCYdcKajpt0G9jMo8mImgg.png)
总结思想 (Closing Thoughts)
Well, it is difficult to decide which one is the optimal choice as it completely depends on the requirements. But, as we know how important data is, we have to make a cautious decision while copying Objects in Javascript.
好吧,很难决定哪个是最佳选择,因为它完全取决于需求。 但是,由于我们知道数据的重要性,因此在用Javascript复制对象时必须做出谨慎的决定。
I hope, this article helps you to understand the differentiation of Shallow Copy and Deep Copy.
希望本文能帮助您了解浅拷贝和深拷贝的区别。
Thanks for Reading!!…
谢谢阅读!!…
Watch out our space ‘The JS Bifrost’ for decoding Javascript the Globant way.
留意我们的空间“ JS Bifrost ”,以全球语言方式解码Javascript。
参考文献: (References :)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_syntax
https://lodash.com/docs/4.17.15#cloneDeep
https://lodash.com/docs/4.17.15#cloneDeep
https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0
https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0
翻译自: https://medium.com/globant/the-js-bifrost-shallow-or-deep-copy-22144e6787d6