Home > Article > Web Front-end > In-depth analysis of object copy methods in JavaScript (with code)
In the previous article "What you need to know about the use of JavaScript "jquery inheritance" (detailed code explanation)", we learned about the use of JavaScript "jquery inheritance". The following article will introduce you to the object copy method in JS. Friends in need can refer to it.
When it comes to object copying in javascript
, the first thing we think of is Object.assign()
JSON.parse(JSON.stringify()),
and ES6
’s expansion operator [...
]
Because in js
=
operator cannot create a copy for an object, it is just a reference to the object
var x = { a: 1, b: 2, }; y = x; x.a = 10; console.log(x); //{a:10, b:2} console.log(y); //{a:10, b:2}
Therefore, when performing object operations, the equal operator (=
) is not advisable
var x = { a: 1, b: 2, }; y = Object.assign({}, x); x.a = 10; console.log(x); //{a:10, b:2} console.log(y); //{a:1, b:2}
At first glance, it is not An exception will be found, because what we want is the result we want. If we make the object structure a little more complicated and look at it
var x = { a: 1, b: 2, c: { d: 3, }, }; y = Object.assign({}, x); x.a = 5; console.log(x); //{a:5, b:2, c:{d:3}} console.log(y); //{a:5, b:2, c:{d:3}} x.c.d = 10; console.log(x); //{a:5, b:2, c:{d:10}} console.log(y); //{a:5, b:2, c:{d:10}}
, we will find a pitfall at this time, then it has been provedObject.assign()
Only implements a shallow copy of the object
Object.assign()
Another thing to note is that non-enumerable objects with attributes on the prototype chain cannot be copied. Take a look at the code. :
var x = { a: 1, }; var y = Object.create(x, { b: { value: 2, }, c: { value: 3, enumerable: true, }, }); var z = Object.assign({}, y); console.log(z); //{c:3}
is surprising to get the value of z
, because x
is the prototype chain of y
, so x
Will not be copied
Attributeb
is a non-enumerable property and will not be copied
Only c
has an enumerable description, he can be Enumeration, so it can be copied
The above pitfalls can also be solved very well, and look down:
JSON.parse(JSON.stringify())
Solution to the pitfalls of shallow copy
var x = { a: 1, b: 2, c: { d: 3, }, }; y = JSON.parse(JSON.stringify(x)); x.a = 5; x.c.d = 10; console.log(x); //{a:5, b:2, c:{d:10}} console.log(y); //{a:1, b:2, c:{d:3}}
Of course, for ordinary objects, this copying method is basically perfect, so where is its pitfall
var x = { a: 1, b: function b() { return "2"; }, }; y = JSON.parse(JSON.stringify(x)); z = Object.assign({}, x); console.log(y); //{a:1} console.log(z); //{a:1, b:function b(){return '2'}}
From the results, Object.assign()
can copy the method, JSON.parse(JSON.stringify())
cannot
Let’s look at the second one A pitfall:
var x = { a: 1, b: { c: 2, d: 3, }, }; x.c = x.b; x.d = x.a; x.b.c = x.c; x.b.d = x.d; var y = JSON.parse(JSON.stringify(x)); console.log(x); /* Uncaught TypeError: Converting circular structure to JSON at JSON.stringify (<anonymous>) at <anonymous>:8:25 */
reported an error, and the result shows that JSON.parse(JSON.stringify()),
cannot copy the circular reference object
Let’s take a look Object.assign()
var x = { a: 1, b: { c: 2, d: 3, }, }; x.c = x.b; x.d = x.a; x.b.c = x.c; x.b.d = x.d; var y = Object.assign({}, x); console.log(x); /* [object Object]{ a:1, b:[object, Object], d:[object, Object], d:1 } */
The expansion operator for object literals is currently ECMAScript
's Phase 3 proposal makes copying objects simpler
var x = [ "a", "b", "c", "d", { e: 1, }, ]; var y = [...x]; console.log(y); //['a', 'b', 'c', 'd', {'e':1}] var m = { a: 1, b: 2, c: ["d", "e"], }; var n = { ...m, }; console.log(n); //{a:1, b:2, c:['d', 'e']}
It should be noted that the spread operator is also a shallow copy. So is it really so difficult to copy objects?
function copy(x) { var y = {}; for (m in x) { y[m] = x[m]; } return y; } var o = { a: 1, b: 2, c: { d: 3, e: 4, }, }; var p = copy(o);
Some people say that there shouldn’t be much problem if you do this. Then we can only laugh and keep going
var x = {}; Object.defineProperty(x, "m", { value: 5, writable: false, }); console.log(x.m); //5 x.m = 25; //这一步没报错,但是也没执行 console.log(x.m); //5
In this way, the expansion operator will also encounter pitfalls when copying objects here.
There are pitfalls everywhere, and it’s hard to guard against them.... As I write this, I guess there are still many pitfalls that haven’t been fully listed.
I’ll write more later
[End]
Recommended learning: JavaScript video tutorial
The above is the detailed content of In-depth analysis of object copy methods in JavaScript (with code). For more information, please follow other related articles on the PHP Chinese website!