In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly explains "the detailed explanation of javascript deep copy, shallow copy and circular citation". Interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "the detailed explanation of javascript deep copy, shallow copy and circular citation".
First, why are there deep copies and shallow copies?
This starts with the data types in js, where data types are divided into basic data types and reference data types.
Basic type values refer to simple segments of data that are stored in stack memory, that is, the value is a location that is completely stored in memory. Contains Number,String,Boolean,Null,Undefined, Symbol.
Reference type values refer to objects stored in heap memory, so the value of the reference type holds a pointer to an object stored in the heap. In addition to the above six basic data types, the rest are reference types, collectively referred to as Object types. Subdivided into: Object type, Array type, Date type, RegExp type, Function type and so on.
Because of this mechanism of reference types, when we copy the value of a reference type from one variable to another, we actually copy a copy of the reference address of the reference type in stack memory to the new variable, which is actually a pointer. So when the operation is over, these two variables actually point to the same object in heap memory, and if you change either object, the other object will change as well.
Therefore, deep and shallow copies only occur in reference types. Simply put, the difference between them is:
1. Layers
Shallow copy only replicates the properties of the object in turn, not recursively, that is, only the first layer properties of the target object are assigned.
Deep copy differs from shallow copy in that it not only copies the first layer attributes of the target object, but also recursively copies all the attributes of the target object.
two。 Whether to open up a new stack
A shallow copy of the data whose first layer is the basic data type of the target object is a direct assignment, that is, "passing value". For the data whose first layer of the target object is the reference data type, that is, the heap memory address, which is directly stored in the stack memory, that is, "passing address", does not open up a new stack, that is, the result of replication is that two objects point to the same address. modify the properties of one object, and the properties of the other object will also change.
Deep copy and deep copy is to open up a new stack. Two objects correspond to two different addresses. Modifying the properties of one object will not change the properties of the other.
2. Shallow copy
Here are several ways to implement shallow copy:
1.Array.concat ()
Const arr = [1Jing 2, 3jue 4, [5jue 6]]; const copy = arr.concat ();\\ create a copy of arr using concat ()\\ change the basic type value, without changing the original array copy [0] = 2; arr; / / [1J 2J 3J 4, [5J 6]];\\ change the value of the reference type in the array, and the original array will also change copy [4] [1] = 7; arr; / / [1J 2J 3J 4, [5J 7]]
Other people who can achieve similar effects are slice () and Array.from (). You can try it yourself.
2.Object.assign ()
Const obj1 = {x: 1, y: 2}; const obj2 = Object.assign ({}, obj1); obj2.x = 2;\\ modify obj2.x to change the basic type value console.log (obj1) / / {x: 1, y: 2} / / the original object does not change console.log (obj2) / / {x: 2, y: 2} const obj1 = {x: 1, y: {m: 1}} Const obj2 = Object.assign ({}, obj1); obj2.y.m = 2;\\ modify obj2.y.m to change the reference type value console.log (obj1) / / {x: 1, y: {m: 2}} the original object is also changed console.log (obj2) / / {x: 2, y: {m: 2}}
III. Deep copy
1.JSON.parse () and JSON.stringify ()
Const obj1 = {x: 1, y: {m: 1}}; const obj2 = JSON.parse (JSON.stringify (obj1)); console.log (obj1) / / {x: 1, y: {m: 1}} console.log (obj2) / / {x: 1, y: {m: 1}} obj2.y.m = 2 / / modify obj2.y.mconsole.log (obj1) / / {x: 1, y: {m: 1}} the original object has not changed console.log (obj2) / / {x: 2, y: {m: 2}}
This method is relatively simple to use, can meet basic day-to-day deep copy requirements, and can handle all data types that can be represented in JSON format, but has the following disadvantages:
Undefined, arbitrary functions, regular expression types, and symbol values are ignored during serialization (when they appear in property values of non-array objects) or converted to null (when they appear in an array)
It discards the constructor of the object. That is, after a deep copy, no matter what the original constructor of the object is, it will become Object after the deep copy.
If there is a circular reference in the object, it cannot be handled correctly.
two。 Recursion
Function deepCopy1 (obj) {/ / create a new object let result = {} let keys = Object.keys (obj), key = null, temp = null; for (let I = 0; I)
< keys.length; i++) { key = keys[i]; temp = obj[key]; // 如果字段的值也是一个对象则递归操作 if (temp && typeof temp === 'object') { result[key] = deepCopy(temp); } else { // 否则直接赋值给新对象 result[key] = temp; } } return result;}const obj1 = { x: { m: 1 }, y: undefined, z: function add(z1, z2) { return z1 + z2 }, a: Symbol("foo")};const obj2 = deepCopy1(obj1);obj2.x.m = 2;console.log(obj1); //{x: {m: 1}, y: undefined, z: ƒ, a: Symbol(foo)}console.log(obj2); //{x: {m: 2}, y: undefined, z: ƒ, a: Symbol(foo)} 四、循环引用 看似递归已经完全解决我们的问题了,然而还有一种情况我们没考虑到,那就是循环引用 1.父级引用 这里的父级引用指的是,当对象的某个属性,正是这个对象本身,此时我们如果进行深拷贝,可能会在子元素->Parent object-> child element. This loop goes on all the time, resulting in a stack overflow. For example, the following example:
Const obj1 = {x: 1, y: 2}; obj1.z = obj1;const obj2 = deepCopy1 (obj1);\\ Stack overflow
The solution is that you only need to determine whether the field of an object refers to the object or any parent of the object, and you can modify the deepCopy function above:
Function deepCopy2 (obj, parent=null) {/ / create a new object let result = {}; let keys = Object.keys (obj), key = null, temp = null, _ parent= parent / / if the field has a parent, you need to trace the parent of the field while (_ parent) {/ / if the field references its parent, it is a circular reference if (_ parent.originParent = obj) {/ / the circular reference returns a new object of the same level, return _ parent.currentParent;} _ parent = _ parent.parent} for (let iReferenkeys.principthteri
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.