What this article brings to you is what are the implementation methods of shallow copy and deep copy in js? (Summary), it has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
js has five basic data types, string, number, boolean, null, and undefind. These five types of assignments are value transfer. The assignment of an object is to assign a reference to the object address. At this time, modifying the properties or values in the object will cause the values of all references to the object to change. If you want to actually copy a new object instead of copying a reference to the object, you must use a deep copy of the object.
Not much to say, the most basic assignment method is just to assign a reference to an object.
Object.assign is a new function in ES6. The Object.assign() method can copy any number of the source object's own enumerable properties to the target object, and then return the target object. However, Object.assign() performs a shallow copy, copying references to the properties of the object, not the object itself.
Object.assign(target, ...sources)
Parameters:
target: target object.
sources: any number of source objects.
Return value: The target object will be returned.
var obj = { a: {a: "hello", b: 21} }; var initalObj = Object.assign({}, obj); initalObj.a.a = "changed"; console.log(obj.a.a); // "changed"
It should be noted that:
Object.assign() can handle a deep copy of one layer, as follows:
var obj1 = { a: 10, b: 20, c: 30 }; var obj2 = Object.assign({}, obj1); obj2.b = 100; console.log(obj1); // { a: 10, b: 20, c: 30 } <-- 沒被改到 console.log(obj2); // { a: 10, b: 100, c: 30 }
var obj1 = { a: 10, b: 20, c: 30 }; var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c }; obj2.b = 100; console.log(obj1); // { a: 10, b: 20, c: 30 } <-- 沒被改到 console.log(obj2); // { a: 10, b: 100, c: 30 }
Use JSON.stringify to convert the object into a string, and then use JSON.parse to convert the string into a new object.
var obj1 = { body: { a: 10 } }; var obj2 = JSON.parse(JSON.stringify(obj1)); obj2.body.a = 20; console.log(obj1); // { body: { a: 10 } } <-- 沒被改到 console.log(obj2); // { body: { a: 20 } } console.log(obj1 === obj2); // false console.log(obj1.body === obj2.body); // false
This is true Deep Copy, this method is simple and easy to use.
But this method also has many disadvantages, for example, it will discard the object's constructor. That is to say, after deep copying, no matter what the original constructor of the object is, it will become Object after deep copying.
The only objects that this method can correctly handle are Number, String, Boolean, Array, and flat objects, that is, those data structures that can be directly represented by json. RegExp objects cannot be deep copied in this way.
In other words, only objects that can be converted into JSON format can be used in this way. Functions cannot be converted into JSON.
var obj1 = { fun: function(){ console.log(123) } }; var obj2 = JSON.parse(JSON.stringify(obj1)); console.log(typeof obj1.fun); // 'function' console.log(typeof obj2.fun); // 'undefined' <-- 没复制
function deepClone(initalObj, finalObj) { var obj = finalObj || {}; for (var i in initalObj) { var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况 if(prop === obj) { continue; } if (typeof prop === 'object') { obj[i] = (prop.constructor === Array) ? [] : {}; arguments.callee(prop, obj[i]); } else { obj[i] = prop; } } return obj; } var str = {}; var obj = { a: {a: "hello", b: 21} }; deepClone(obj, str); console.log(str.a);
Use var newObj = Object.create(oldObj) directly to achieve deep copying Effect.
function deepClone(initalObj, finalObj) { var obj = finalObj || {}; for (var i in initalObj) { var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况 if(prop === obj) { continue; } if (typeof prop === 'object') { obj[i] = (prop.constructor === Array) ? [] : Object.create(prop); } else { obj[i] = prop; } } return obj; }
jquery provides a $.extend that can be used for 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
There are also some other third-party function libraries with deep copy functions, such as lodash.
The above is the detailed content of What are the implementation methods of shallow copy and deep copy in js? (Summarize). For more information, please follow other related articles on the PHP Chinese website!