Javascript浅拷贝与深拷贝

       浅拷贝是指只复制一层对象,当对象的属性是引用类型时,实质复制的是其引用,当引用指向的值改变时也会跟着变化;

      深拷贝是指复制对象的所有层级。

 1. 浅拷贝

 浅拷贝的方法: Object.assign

    let obj = {a: 1, b: {title: 'hello', name: 'John'}}
    let obj1 = Object.assign({}, obj)
    obj.a = 2
    obj.b.name = 'Smith'
    console.log(obj1.a, obj1.b.name) // 1 Smith

  可见,obj的a属性改变时,不影响obj1中a的改变;但引用类型,b中属性值的改变会同步到obj1。

        实现浅拷贝的方法还可以使用 ...展开运算符

1     let obj = {a: 1, b: {title: 'hello', name: 'John'}}
2     let obj1 = {...obj}
3     obj.a = 2
4     obj.b.name = 'Smith'
5     console.log(obj1.a, obj1.b.name) // 1 Smith

  我们可以手动实现一个简单的浅拷贝函数,如下:

 1   function closeShallow(source) {
 2       var target = Object.create(null)
 3       for (let key in source) {
 4         if (Object.prototype.hasOwnProperty.call(source, key)) {
 5           target[key] = source[key]
 6         }
 7       }
 8       return target
 9     }
10     let obj = {a: 1, b: {title: 'hello', name: 'John'}}
11     let obj1 = closeShallow(obj)
12     obj.a = 2
13     obj.b.name = 'Smith'
14     console.log(obj1.a, obj1.b.name) // 1 Smith

2. 深拷贝

深拷贝的方法JSON.parse(JSON.stringify())

1     let obj = {a: 1, b: {title: 'hello', name: 'John'}}
2     let obj1 = JSON.parse(JSON.stringify(obj))
3     obj.a = 2
4     obj.b.name = 'Smith'
5     console.log(obj1.a, obj1.b.name) // 1 John

也以使用lodash的cloneDeep方法来实现

手动实现深拷贝实际上是在浅拷贝的基础上使用递归调用,代码如下:

    function cloneDeep(source) {
      var target = Object.create(null)
      for (let key in source) {
        if (Object.prototype.hasOwnProperty.call(source, key)) {
          if (typeof source[key] === 'object') {
            target[key] = cloneDeep(source[key])
          } else {
            target[key] = source[key]
          }
        }
      }
      return target
    }
    let obj = {a: 1, b: {title: 'hello', name: 'John'}}
    let obj1 = cloneDeep(obj)
    obj.a = 2
    obj.b.name = 'Smith'
    console.log(obj1.a, obj1.b.name) // 1 John

 

上一篇:构造函数继承--call,apply


下一篇:PHP面试常考内容之面向对象(2)