热搜:前端 nest neovim nvim

js对象的拷贝有几种方法(js对象拷贝方式)

lxf2023-02-26 12:48:01

在之前的文章《JavaScript继承jquery》中,我们了解了JavaScript“继承jquery”的使用方法。下面这篇文章将为您了解JS中对象的复制方法,有需要的朋友可以参考。

js对象的拷贝有几种方法(js对象拷贝方式)

说到javascript对象复制,首先我们想到的是对象复制,Object.assign()

JSON.parse(JSON.stringify()),还有ES6展开操作符[...]

因为在js=运算符 对于对象,不能创建副本,只能引用对象

运算符

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}

因此,在对象操作中,运算符等于号(=)不可取

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}

一开始,我们不会发现异常,因为我们想要的是我们想要的结果。让对象结构稍微复杂一点,然后再看。

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}}

这时发现了坑,所以已经证明了Object.assign()只是实现了对象的浅拷贝

Object.assign()还需要注意的是,原型链上不可枚举的属性对象无法复制。看看代码:

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}

拿到z值非常令人惊讶,因为值非常令人惊讶,因为xy原型链,所以x不会被复制

属性b是不可枚举的属性,也不会被复制

只有c有可枚举描述,他可以被枚举,所以可以被复制

上述坑也可以很好地解决,并往下看:

深拷贝JSON.parse(JSON.stringify())

解决浅拷贝坑

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}}

当然,普通对象,这种复制方法基本上是完美的,那么他的坑在哪里呢?

var x = {
  a: 1,
  b: function b() {
    return