【Javascript】赋值、深拷贝、浅拷贝

前置知识

js中的常见类型:

基本类型(原始类型):number、string、boolean、null、undefind

引用类型:object

注:变量存储在栈内存中,对象存储在堆内存中。

浅拷贝:

浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。

如果属性是基本类型,拷贝的就是基本类型的值。

如果属性是引用类型,拷贝的就是内存地址,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。

深拷贝:

深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。


针对引用类型来说  赋值 深拷贝 浅拷贝的区别:

赋值:

当我们把一个对象赋值给一个新的变量时,赋的其实是该对象在栈中的地址,而不是堆中的数据。也就是两个对象指向的是同一个存储空间,无论哪个对象发生改变,其实都是改变的存储空间的内容,因此两个对象是联动的。

赋值的例题:

我们可以看到原对象的name和hobby[0]都被改了。

 

浅拷贝:

重新在堆中创建内存,拷贝前后对象的基本数据类型互不影响,但拷贝前后对象的引用类型因共享同一块内存,会互相影响。

注:浅拷贝只遍历一层,并不包含子对象。

浅拷贝的例题:

我们可以看到原对象中属于基本类型的name没有被更改,而属于引用类型的hobby[0]被更改了。

 

深拷贝:

从堆内存中开辟一个新的区域存放新对象,对对象的子对象进行递归拷贝,拷贝前后的两个对象互不影响。

我们可以看到原对象的name和hobby[0]均未被改变。

 

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>浅拷贝</title>
</head>
<body>
  <script>
    var person = {
      name: '张三',
      hobby: ['学习',['看电影','购物'],['跑步']]
    }

    function shallowCopy(obj) {
      var target = {}
      for( var i in obj ) {
        if(obj.hasOwnProperty(i)) {
          target[i] = obj[i]
        }
      }
      return target
    }

    var person1 = shallowCopy(person)
    person1.name = '李四'
    person1.hobby[0] = '玩耍'

    console.log(person)
    console.log(person1)

  </script>
</body>
</html>

 

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>深拷贝</title>
</head>
<body>
  <script>
    var person = {
      name: '张三',
      hobby: ['学习',['看电影','购物'],['跑步']]
    }

    function deepClone(obj) {
      var cloneObj = new obj.constructor()
      if(obj ===null) return obj
      if(obj instanceof Date) return new Date(obj)
      if(obj instanceof RegExp) return new RegExp(obj)
      if(typeof obj !== 'object') return
      for(var i in obj) {
        if(obj.hasOwnProperty(i)) {
          cloneObj[i] = deepClone(obj[i])
        }
      }
      return cloneObj
    }

    var person1 = deepClone(person)
    person1.name = '李四'
    person1.hobby[0] = '玩耍'

    console.log(person)
    console.log(person1)

  </script>
</body>
</html>

ps:instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值