01前端/JS - 对象的深拷贝和浅拷贝

拷贝对象分为浅拷贝和深拷贝,深拷贝只会复制地址,深拷贝才会复制内容,那么 JS 如何进行这两种拷贝呢?

浅拷贝

Object.assign() 方法

Object.assign() - JavaScript | MDN

1
2
3
4
5
6
7
8
9
10
11
var object1 = {
a: [1],
b: 2,
c: 3
};

var object2 = Object.assign({}, object1);
console.log(object2.a); // [1]

object1.a[0] = 111;
console.log(object2.a); // [111]

深拷贝

$.extend() 方法

jQuery.extend() | jQuery API Documentation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var jsdom = require("jsdom").JSDOM;
var window = new jsdom(`<!DOCTYPE html>`).window;
var $ = require("jquery")(window);

var object1 = {
a: [1],
b: 2,
c: 3
};

var object2 = $.extend(true, {}, object1);
console.log(object2.a); // [1]

object1.a[0] = 111;
console.log(object2.a); // [1]

_.cloneDeep() 方法

cloneDeep | Lodash Documentation

1
2
3
4
5
6
7
8
9
10
11
12
13
var _ = require("lodash");

var object1 = {
a: [1],
b: 2,
c: 3
};

var object2 = _.cloneDeep(object1);
console.log(object2.a); // [1]

object1.a[0] = 111;
console.log(object2.a); // [1]

注意

lodash 拷贝数组,数组上的属性会丢失

作者已经指出这不是 bug,而是这样设计的:clone does not copy array properties · Issue #3521 · lodash/lodash

PS:使用 jquery 拷贝不会这样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var jsdom = require("jsdom").JSDOM;
var window = new jsdom(`<!DOCTYPE html>`).window;
var $ = require("jquery")(window);
var _ = require("lodash");

var object1 = {
a: [1],
b: 2,
c: 3
};

object1.a.p1 = 123;

var jq_obj = $.extend(true, {}, object1);
var lo_obj = _.cloneDeep(object1);

console.log(jq_obj.a); // [1, p1: 123]
console.log(lo_obj.a); // [1]