In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces the relevant knowledge of "how to achieve JavaScript shallow copy and deep copy". The editor shows you the operation process through an actual case. The operation method is simple, fast and practical. I hope this article "how to achieve JavaScript shallow copy and deep copy" can help you solve the problem.
There are two sets of variable type data in JavaScript, the basic type and the reference type. Copying the value type copies the value of the variable, which is unrelated to each other. The reference type only copies the pointer address of the stored variable, causing two variables to point to the same address, that is, the same data, and modifying one of them will directly affect the other. The shallow copy and deep copy we are going to talk about refer to the reference type.
I. preliminary knowledge
1.1.The JS data type
Basic data types: Boolean, String, Number, null, undefined reference data types: Object, Array, Function, RegExp, Date, etc.
1.2. Replication of data types
Replication of basic data types, passed by value
Var a = 1 var b = a * b = 2 * console.log (a); / / (b); / / 2
Replication of reference data types, passing values by reference
Var obj1 = {a: 1 b: 2;}; var obj2 = obj1;obj2.a=3;console.log (obj1.a); / / 3console.log (obj2.a); / / 3
1.3. Deep copy and shallow copy
Both deep copy and shallow copy are only for reference data types. Shallow copy will copy the object member by member, but only copy the memory address, but not copy the object itself, the new and old object members still share the same memory; deep copy will create another identical object, the new object does not share memory with the original object, and modifying the new object will not change to the original object.
Difference: a shallow copy copies only the first layer attributes of an object, while a deep copy recursively copies the attributes of an object.
II. JS shallow copy
2.1, assignment and shallow copy
When an object is assigned to a new variable, the assigned object is the address of the object in the stack, not the data in the heap. That is, the new and old objects refer to the same storage space, no matter which object changes, it is actually the content of the changed storage space, and the linkage of the two objects will change together.
Var obj1 = {'name':' zhangsan', 'language': [1, [2 obj1',obj1 3], [4 obj2',obj2 5]],}; var obj2 = obj1;obj2.name = "lisi"; obj2.language [1] = ["2", "3"]; console.log (' obj1',obj1) console.log ('obj2',obj2)
A shallow copy is a bitwise copy object, which creates a new object and copies the members of the original object in turn. If the attribute is a base type, the value of the base type is copied; if the property is a reference type, the memory address is copied. So if an object member in the new object changes the address, the original object will be affected.
/ handwritten shallow copy function shallowCopy (obj1) {let obj2 = Array.isArray (obj1)? []: {} for (let i in obj1) {obj2 [I] = obj1 [I]} return obj2} var obj1 = {'name':' zhangsan', 'language': [1, [2jue 3], [4jue 5],}; var obj2 = shallowCopy (obj1); obj2.name = "lisi"; obj2.language [1] = ["two", "three"] Console.log ('obj1',obj1) console.log (' obj2',obj2)
Show details
Img
2.2. The realization of shallow copy
(1) Object.assign ()
The Object.assign () method can copy any number of enumerable properties of the source object itself to the target object, and then return the target object, but Object.assign () makes a shallow copy, copying a reference to the object's properties, not the object itself. This method is applicable to both Array and Object.
?
Var obj1 = {'name':' zhangsan', 'language': [1, [2 obj1',obj1 3], [4 obj1',obj1 5]],}; var obj2 = Object.assign ({}, obj1); obj2.name = "lisi"; obj2.language [1] = ["2", "3"]; console.log (' obj1',obj1) console.log ('obj2',obj2) img
(2) Array.prototype.concat () and Array.prototype.slice ()
Array.prototype.concat () and Array.prototype.slice () are both methods on the Array prototype and are only applicable to Array.
Var arr1 = [1console.log 3, {user: 'aaa'}] var arr2 = arr1.concat (); arr2 [0] =' one'; arr2 [2] .user = 'AAA';console.log (' arr1',arr1) console.log ('arr2',arr2) var arr1 = [1p3, {user:' aaa'}] var arr2 = arr1.slice (); arr2 [0] = 'one'; arr2 [2] .user = 'AAA';console.log (' arr1',arr1) console.log ('arr2',arr2)
Show details
Img
Note: Array's slice and contact methods do not modify the original array, but return a new array that makes a shallow copy of the original array. Both methods, like Object.assign (), copy the first-tier attributes in turn, copying the value if the first-tier attribute is a basic data type, and copying the memory address if it is a reference data type.
III. Deep copy of JS
Traverses the values of all reference types in the properties of the object until they are values of the base type.
3.1. Implementation of deep copy
(1) JSON.parse (JSON.stringify ())
Principle: use JSON.stringify () to convert the object into a string, and then use JSON.parse () to parse the string into an object.
Var obj1 = {'name':' zhangsan', 'language': [1, [2pje 3], [4jre 5]],}; var obj2 = JSON.parse (JSON.stringify (obj1)); obj2.name = "lisi"; obj2.language [1] = ["II", "III"]; console.log (' obj1',obj1) console.log ('obj2',obj2) img
Disadvantages: this approach can make deep copies of arrays and objects and basic data types, but cannot handle functions. Because the JSON.stringify () method converts a javascript value to a JSON string, it cannot accept a function. Other effects are as follows:
If there is a time object in the object, then in the object copied by this method, the time is in the form of a string rather than a time object. If there are RegExp or Error objects in the object, then the result of serialization is null. If there is a function or undefined in the object, then the serialization result will lose the function or undefined if there are NAN, infinity,-infinity in the object. Then the result of serialization will become that nullJSON.stringfy () can only serialize the enumerable self-owned properties of the object. If any of the objects are generated by the constructor, the constructor of the object will be discarded after copying. If there is a circular reference in the object, the deep copy cannot be implemented correctly.
(2) handwritten deep copy function
Deep copy through recursion
Function deepCopy (obj) {var result= Array.isArray (obj)? []: {} if (obj & & typeof (obj) = 'object') {for (let i in obj) {if (obj.hasOwnProperty (I)) {/ / think: is this sentence necessary? If (obj [I] & & typeof (obj [I]) = = 'object') {result [I] = deepCopy (OBJ [I])} else {result [I] = obj [I]} return result} var obj1 = {a: 1var obj2 b: {c: 2}}; var obj2 = deepCopy (obj1); obj2.a =' one'; obj2.b.c = 'two' console.log ('obj1', obj1) console.log (' obj2', obj2)
Show details
❝
Obj.hasOwnProperty (prop) is used to determine whether the obj object contains the attribute prop. It returns a Boolean value, such as true, or false.
There is a flaw in the above: when two objects that reference each other are encountered, there will be an endless loop, resulting in a stack explosion. In order to avoid an endless loop caused by mutually referenced objects, you should determine whether or not to refer to each other when traversing.
Deep copy function improvement (to prevent cyclic recursion from exploding the stack)
Function deepCopy (obj, parent = null) {let result = Array.isArray (obj)? []: {} let _ 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 Return a new object of the same level return _ parent.currentParent} _ parent = _ parent.parent} if (obj & & typeof (obj) = 'object') {for (let i in obj) {/ / if the value of the field is also an object if (obj [I] & & typeof (obj [I]) = =' object') {/ / Recursive perform deep copy Pass the objects to be copied at the same level to parent to facilitate the traceability of circular references result [I] = deepCopy (obj [I], {originalParent: obj, currentParent: result, parent: parent})} else {result [I] = obj [I]}} return result} var obj1 = {x: 1Magy: 2} Obj1.z = obj1var obj2 = deepCopy (obj1) console.log ('obj1', obj1) console.log (' obj2', obj2)
Show details
The above code can be copied to the browser to try it.
Final version of deep copy function (supports basic data types, Array, Object, prototype chain, RegExp, Date types)
Function deepCopy (obj, parent = null) {let resultlet _ parent = parentwhile (_ parent) {if (_ parent.originalParent = obj) {return _ parent.currentParent} _ parent = _ parent.parent} if (obj & & typeof (obj) = = 'object') {if (obj instanceof RegExp) {result = new RegExp (obj.source) Obj.flags)} else if (obj instanceof Date) {result = new Date (obj.getTime ())} else {if (obj instanceof Array) {result = []} else {let proto = Object.getPrototypeOf (obj) result = Object.create (proto)} for (let i in obj) {if (obj [I] & & typeof (OBJ [I]) = = 'object') {result [I] = deepCopy (obj [I], {originalParent: obj, currentParent: result Parent: parent})} else {result [I] = obj [I]}} else {return obj} return result} var obj1 = {x: 1} / / try calling function construct () {this.a = 1, this.b = {x this.a 2, y this.a 3, z: [4jue 5, [6]}, this.c = [7je 8, [9jue 10]], this.d = new Date (), this.e = / abc/ig, this.f = function (a) B) {return ahumb}, this.g = null, this.h = undefined, this.i = "hello", this.j = Symbol ("foo")} construct.prototype.str = "Ihumm prototype" var obj1 = new construct () obj1.k = obj1obj2 = deepCopy (obj1) obj2.b.x = 999obj2.c [0] = 666console.log ('obj1', obj1) console.log (' obj2', obj2)
Show details
(3) function library
You can also use some function libraries, such as lodash, or provide _ .cloneDeep to make deep copies.
Var _ = require ('lodash'); var obj1 = {a: 1, b: {f: {g: 1}}, c: [1,2,3]}; var obj2 = _ .cloneDeep (obj1); console.log (obj1.b.f = obj2.b.f); / / false on "how to achieve JavaScript shallow copy and deep copy", thank you for reading. If you want to know more about the industry, you can follow the industry information channel. The editor will update different knowledge points for you every day.
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.