Home  >  Article  >  Web Front-end  >  In-depth analysis of object copy methods in JavaScript (with code)

In-depth analysis of object copy methods in JavaScript (with code)

奋力向前
奋力向前forward
2021-08-20 09:55:371916browse

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.

In-depth analysis of object copy methods in JavaScript (with code)

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

Operator

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

Object.assign()

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:

Deep copyJSON.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
}
*/

Use the expansion operator [... ]

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); //[&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, {&#39;e&#39;:1}]

var m = {
  a: 1,
  b: 2,
  c: ["d", "e"],
};
var n = {
  ...m,
};
console.log(n); //{a:1, b:2, c:[&#39;d&#39;, &#39;e&#39;]}

It should be noted that the spread operator is also a shallow copy. So is it really so difficult to copy objects?

Invent your own wheel:

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!

Statement:
This article is reproduced at:chuchur.com. If there is any infringement, please contact admin@php.cn delete