Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to understand Javascript deep copy and shallow copy

2025-01-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

How to understand Javascript deep copy and shallow copy? in view of this problem, this article introduces the corresponding analysis and solution in detail, hoping to help more partners who want to solve this problem to find a more simple and feasible method.

Preface

There are different ways to copy objects in javascript. If you are not familiar with the language, it is easy to fall into a trap when copying objects, so how can we copy an object correctly?

Shallow copy and deep copy

A shallow copy creates a new object that has an exact copy of the original object property value. If the attribute is a base type, the value of the base type is copied, and if the property is a reference type, the copy is the memory address, so if one object changes this address, it will affect the other object.

Deep copy is a complete copy of an object from memory, opening up a new area from the heap memory to store the new object, and modifying the new object will not affect the original object.

Var A1 = {b: {c: {}}; var a2 = shallowClone (A1); / / shallow copy method a2.b.c = = a1.b.c / / true old and new objects still share the same memory var A3 = deepClone (A3); / / Deep copy method a3.b.c = a1.b.c / / false New objects do not share memory with the original object

With the help of the following two pictures of ConardLi boss, we can better understand the meaning of the two:

In short, the shallow copy only copies the pointer to an object, not the object itself, and the new and old objects still share the same piece of memory. However, a deep copy will create an 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.

The difference between assignment and deep / shallow copy

The differences between the three are as follows, but the premise of the comparison is for the reference type:

When we assign an object to a new variable, it is actually the address of the object in the stack, not the data in the heap. That is, two objects point to the same storage space, no matter which object changes, it is actually the content of the changed storage space, so the two objects are linked.

Shallow copy: re-create memory in the heap, the basic data types of objects before and after copying do not affect each other, but the reference types of objects before and after copying will affect each other because they share the same piece of memory.

Deep copy: open a new area from the heap memory to store new objects, recursively copy the sub-objects in the object, and the two objects before and after the copy do not affect each other.

Let's first look at the following example to compare the impact of the modification of the object obtained by the assignment and the deep / shallow copy on the original object:

/ / object assignment let obj1 = {name: 'sailing in the waves', arr: [1, [2jue 3], 4],}; let obj2 = obj1; obj2.name = "A Lang"; obj2.arr [1] = [5Jet 6JE7] Console.log ('obj1',obj1) / / obj1 {name:' Ah Lang', arr: [1, [5, 6, 7], 4]} console.log ('obj2',obj2) / / obj2 {name:' A Lang', arr: [1, [5, 6, 7], 4]} / / shallow copy let obj1 = {name: 'boat in waves', arr: [1, [2, 3], 4],},} Let obj3=shallowClone (obj1) obj3.name = "A Lang"; obj3.arr [1] = [5pcmt / 7]; / / the old and new objects still share the same memory / / this is a shallow copy of the method function shallowClone (source) {var target = {}; for (var i in source) {if (source.hasOwnProperty (I)) {target [I] = source [I];} return target } console.log ('obj1',obj1) / / obj1 {name:' boat in the waves', arr: [1, [5, 6, 7], 4]} console.log ('obj3',obj3) / / obj3 {name:' A Lang', arr: [1, [5, 6, 7], 4]} / / Deep copy let obj1 = {name: 'boat in the waves', arr: [1, [2, 3], 4],},} Let obj4=deepClone (obj1) obj4.name = "A Lang"; obj4.arr [1] = [5pcmt / 7]; / / the new object does not share memory with the original object / / this is a deep copy of the method function deepClone (obj) {if (obj = null) return obj; if (obj instanceof Date) return new Date (obj); if (obj instanceof RegExp) return new RegExp (obj); if (typeof obj! = "object") return obj Let cloneObj = new obj.constructor (); for (let key in obj) {if (obj.hasOwnProperty (key)) {/ / implement a recursive copy of cloneObj [key] = deepClone (obj [key]);} return cloneObj } console.log ('obj1',obj1) / / obj1 {name:' sailing in the waves', arr: [1, [2, 3], 4]} console.log ('obj4',obj4) / / obj4 {name:' A Lang', arr: [1, [5, 6, 7], 4]}

In the above example, obj1 is the original object, obj2 is the object obtained by assignment operation, object obtained by shallow copy by obj3, object obtained by deep copy by obj4. Through the table below, we can clearly see their impact on the original data:

The implementation of shallow copy

1.Object.assign ()

The Object.assign () method can copy the enumerable properties of any number of source objects to the target object, and then return the target object.

Let obj1 = {person: {name: "kobe", age: 41}, sports:'basketball'}; let obj2 = Object.assign ({}, obj1); obj2.person.name = "wade"; obj2.sports = 'football' console.log (obj1); / / {person: {name:' wade', age: 41}, sports:'basketball'}

two。 The _ .clone method of function library lodash

This function library also provides _ .clone to be used as Shallow Copy. We will introduce how to use this library to implement deep copy later.

Var _ = require ('lodash'); var obj1 = {a: 1, b: {f: {g: 1}, c: [1,2,3]}; var obj2 = _ .clone (obj1); console.log (obj1.b.f = obj2.b.f); / / true

3. Expand operator.

The expansion operator is an es6 / es2015 feature that provides a very convenient way to perform a shallow copy, which is the same function as Object.assign ().

Let obj1 = {name: 'Kobe', address: {XRO 100 Magi YRU 100}} let obj2= {... Obj1} obj1.address.x = 200; obj1.name = 'wade' console.log (' obj2',obj2) / / obj2 {name: 'Kobe', address: {x: 200, y: 100}}

4.Array.prototype.concat ()

Let arr = [1,3, {username: 'kobe'}]; let arr2 = arr.concat (); arr2 [2] .username =' wade'; console.log (arr); / / [1,3, {username: 'wade'}]

5.Array.prototype.slice ()

Let arr = [1,3, {username: 'kobe'}]; let arr3 = arr.slice (); arr3 [2] .username =' wade' console.log (arr); / / implementation of deep copy of [1,3, {username: 'wade'}]

1.JSON.parse (JSON.stringify ())

Let arr = [1,3, {username: 'kobe'}]; let arr4 = JSON.parse (JSON.stringify (arr)); arr4 [2] .username =' duncan'; console.log (arr, arr4)

This is also using JSON.stringify to convert the object into a JSON string, and then parsing the string into an object with JSON.parse. Once gone, a new object is generated, and the object will open up a new stack to achieve deep copy.

Although this method can make deep copies of arrays or objects, it cannot deal with functions and regularities, because after both JSON.stringify and JSON.parse processing, the resulting regularities are no longer regular (become empty objects), and the resulting functions are no longer functions (become null).

For example, the following example:

Let arr = [1,3, {username: 'kobe'}, function () {}]; let arr4 = JSON.parse (JSON.stringify (arr)); arr4 [2] .username =' duncan'; console.log (arr, arr4)

two。 The _ .cloneDeep method of function library lodash

The function library also provides _ .cloneDeep for Deep Copy.

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

3.jQuery.extend () method

Jquery provides a $.extend that can be used as a Deep Copy

Extend (deepCopy, target, object1, [objectN]) / / the first parameter is true, which is the deep copy var $= require ('jquery'); var obj1 = {a: 1, b: {f: {g: 1}, c: [1,2,3]}; var obj2 = $.extend (true, {}, obj1); console.log (obj1.b.f = obj2.b.f); / / false

4. Handwritten recursive method

The recursive method implements the principle of deep cloning: traversing objects and arrays to the inside are all basic data types, and then copying them, that is, deep copying.

There is a special case that we should pay attention to, that is, there is a circular reference to the object, that is, the property of the object refers to itself directly. To solve the problem of circular reference, we can open up an additional storage space to store the corresponding relationship between the current object and the copied object. When you need to copy the current object, first go to the storage space to find whether the object has been copied, and return directly if there is any. If not, continue to copy, so as to skillfully resolve the problem of circular references. If you have any doubts about this piece, please read carefully how the ConardLi boss wrote a deep copy of the amazing interviewer? This article.

Function deepClone (obj, hash = new WeakMap ()) {if (obj = null) return obj; / / if it is null or undefined, I will not copy if (obj instanceof Date) return new Date (obj); if (obj instanceof RegExp) return new RegExp (obj); / / it may be an object or a normal value. If it is a function, there is no need to deep copy if (typeof obj! = "object") return obj. / / if it is an object, make a deep copy of if (hash.get (obj)) return hash.get (obj); let cloneObj = new obj.constructor (); / / find the constructor on the prototype of the class to which you belong, and the constructor on the prototype points to the hash.set (obj, cloneObj) of the current class itself. For (let key in obj) {if (obj.hasOwnProperty (key)) {/ / implement a recursive copy cloneObj [key] = deepClone (obj [key], hash);}} return cloneObj;} let obj = {name: 1, address: {x: 100}}; obj.o = obj; / / where there is a circular reference to the object let d = deepClone (obj); obj.address.x = 200; console.log (d) This is the answer to the question about how to understand the deep copy and shallow copy of Javascript. I hope the above content can be of some help to you. If you still have a lot of doubts to be solved, you can follow the industry information channel for more related knowledge.

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.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report