JS中的赋值、浅拷贝与深拷贝

58 篇文章 3 订阅

拷贝是写代码中经常使用的方法。浅拷贝与深拷贝是指拷贝的两种情况。本文将深入探究JS的赋值、浅拷贝与深拷贝。

数据类型

  • 在探究深拷贝与浅拷贝之前,我们先梳理一下JS的数据类型。在JavaScript中,数据类型有两大类。一类是基本数据类型,一类是引用数据类型。
  • 基本数据类型有五种:number、string、boolean、null、undefined。基本数据类型存放在栈中。存放在栈中的数据具有数据大小确定,内存空间大小可以分配、直接按值存放的特点。所以存放在栈中的数据可以直接访问。在JavaScript中,基本的数据类型值是不可更改的。可能这一点不符合我们平常的使用认知。我们在修改字符串或其他基本数据类型变量时,实际上是返回了一个新的值,而不是【改变】原始值。
  • 而对于引用数据类型,是存放在堆内存中。引用数据类型的变量并不是存放的实际值,而是一个存放在栈内存的指针,该指针指向堆内存中的某个地址。每个数据所占的空间大小不一致,需要根据情况进行特定的分配。与基本数据类型不同,引用类型的值是可以改变的。

赋值:传值与传址

  • 有了对JavaScript数据类型的一定了解后,我们接下来看看不同类型的数据类型在赋值时的区别。
    对于基本数据类型来说,当我们进行赋值操作(=)时,实际上是在内存中新开一段栈内存,然后再将值赋值到新的栈中。
    举个例子:
	let a = 1
	let b = a
	a = 5
	console.log(a) // 5
	console.log(b) // 1
  • 对于上述语句,b变量虽然是a变量的复制,但与a变量是独立互不影响的变量。
    而对于引用数据类型来说,在进行赋值操作时,实际上是把变量的地址传给了另一个变量,所以称为传址。传址之后,两个变量就指向同一个地址,两者的操作是互有影响的。
    例:
	let a = { age: 12 }
	let b = a
	
	a.age = 13
	console.log(a.age) // 13
	console.log(b.age) // 13
	
	b.age = 14
	console.log(a.age) // 14
	console.log(b.age) // 14

浅拷贝与深拷贝

  • 只有当拷贝引用数据类型时,拷贝才存在浅拷贝与深拷贝之分。

浅拷贝

  • 浅拷贝就是指创建一个新对象,该对象拥有原始对象第一层属性的精确拷贝。即:如果原始对象的属性是基本类型数据,则拷贝的就是基本数据类型的值;如果原始对象的属性是引用类型,则拷贝的是内存地址。当原始对象的引用类型属性发生改变时,拷贝对象的对应属性值也会发生变化。这里需要强调一下,浅拷贝与赋值是有所区别的,赋值时与原数据指向同一对象,而浅拷贝则指向了不同对象。
    让我们来实现一个浅拷贝方法。
	function shallowCopy(src) {
	  const dist = {}
	  for (let prop in src) {
	    if (src.hasOwnProperty(prop)) {
	      dist[prop] = src[prop]
	    }
	  }
	  return dist
	}

深拷贝

  • 浅拷贝是对原始对象第一层属性的精确拷贝,而深拷贝则是对原始对象所有层级属性的递归精确拷贝。
    深拷贝的实现
    JSON:
	jsonCopy(src){
       	let temp = JSON.stringify(src);
        let dist = JSON.parse(temp);
        return dist;
    },
  • 递归实现:
 deepCopy(src){
      if( typeof src !== 'object' ){
          return src;
      }
      if(src == null){
          return null;
      }
      let dist = Array.isArray(src)? [] : {};
      if(src && typeof src == 'object'){
          for(let prop in src){
              if(src.hasOwnProperty(prop)){
                  if(src[prop] && typeof src[prop] == 'object'){
                      dist[prop] = this.deepCopy(src[prop]);
                  }else{
                      // 如果是基本数据类型 只是简单的赋值
                      dist[prop] = src[prop];
                  }
              }
          }
      };
      return dist;
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值