爱客仕-前端团队博客园

饶舌的深浅拷贝

此文提及的浅拷贝排除了a===b的情况[镜像-你变我也变,当然这也不是拷贝]
浅拷贝[克隆初代,后面都是镜像]
深拷贝[克隆全家]

常见拷贝方式

  • Object.assign()
    合并对象,浅拷贝

  • lodash —— _.clone() / _.cloneDeep()
    浅拷贝/深拷贝[遍历浅拷贝]

  • JSON.parse(JSON.stringify(sourceObject))
    常规json的深拷贝取巧方法,效率666

栗子来了

来一波代码,以拷贝对象为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<script src="http://cdn.bootcss.com/lodash.js/4.16.1/lodash.min.js"></script>
<script>
console.group('copy obj test')
let obj = {
a: {
x: 1
},
b: 2
}
// Object.assign()
console.time('assign')
let assign = Object.assign({}, obj)
console.timeEnd('assign')
console.info('assign.a === obj.a->', assign.a === obj.a) // true
// lodash —— _.clone() / _.cloneDeep()
console.time('clone')
let clone = _.clone(obj)
console.timeEnd('clone')
console.info('clone.a === obj.a->', clone.a === obj.a) // true
console.time('cloneDeep')
let cloneDeep = _.cloneDeep(obj)
console.timeEnd('cloneDeep')
console.warn('cloneDeep.a === obj.a->', cloneDeep.a === obj.a) // false
// 借助 JSON 全局对象
console.time('json')
let json = JSON.parse(JSON.stringify(obj))
console.timeEnd('json')
console.warn('json.a === obj.a->', json.a === obj.a) // false
console.groupEnd()
// 浅拷贝互相伤害,深拷贝独善其身
console.group('test')
console.info('初始obj->' + JSON.stringify(obj))
assign.a.x = 4
assign.b = 4
console.info('浅拷贝赋值assign.a.x=4 assign.b=4')
console.warn('结果obj.a.x->' + obj.a.x, 'obj.b->' + obj.b)
json.a.x = 5
json.b = 5
console.info('深拷贝赋值json.a.x=5 json.b=5')
console.warn('结果obj.a.x->' + obj.a.x, 'obj.b->' + obj.b)
console.groupEnd()
</script>

看看控制台出来啥

附图

执行效率排行榜,按需使用,常用就是1&2

  1. Object.assign()
  2. JSON.parse(JSON.stringify())
  3. _.clone()
  4. _.cloneDeep()

使用场景:也不是处处需要深拷贝,想明白拷贝出来是为了达到什么目的,关注效率

不管深浅拷贝,先判断下是否空对象吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 判断是否空对象
let obj = {
a: {
x: 1
},
b: 2
}
console.group('isEmptyObj')
console.time('Object.keys()')
console.info(!Object.keys(obj).length)
console.timeEnd('Object.keys()')
console.time('json')
console.info(JSON.stringify(obj) === '{}')
console.timeEnd('json')
console.groupEnd()

看看控制台出来啥,其实效率也差不多吧。。。

附图

几种比较实用的console玩法

再也不用担心找不到调试信息了。。。

  • 信息分组,可折叠

    1
    2
    3
    console.group('name')
    // ...
    console.groupEnd()
  • 统计执行时间,代码效率如何?拉出来溜溜

    1
    2
    3
    console.time('name')
    // ...
    console.timeEnd('name')
  • 4种信息类型,带了标记,找起来不要太方便哟

    1
    2
    3
    4
    console.log('我是老实人')
    console.info('我是小蓝')
    console.error('我有个小叉子')
    console.warn('我有警告牌')