JavaScript面试精讲(七)——谈谈深拷贝和浅拷贝

一.浅拷贝

浅拷贝
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。即对象的浅拷贝会对“主”对象进行拷贝,但不会复制主对象里面的对象。”里面的对象“会在原来的对象和它的副本之间共享。

 1.JavaScript中变量包含两种不同的数据类型基本数据类型    引用数据类型

  • 基本类型值指的是简单的数据段,包括es6里面新增的一共是有6种,具体如下:number、string、boolean、null、undefined、symbol。

  • 引用类型值指那些可能由多个值构成的对象,只有一种如下:object。
    在将一个值赋给变量时,解析器必须确定这个值是基本类型值还是引用类型值。

2.基本类型与引用类型最大的区别实际就是 传值与传址 的区别

 值传递:基本类型采用的是值传递。
  地址传递:引用类型则是地址传递,将存放在栈内存中的地址赋值给接收的变量。

接下来看几个例子就会理解两者区别

数组

var arra=[1,2,3,4,5]
var arra1=arra
arra1.push(9)
console.log(arra);
console.log(arra1);

 

 向操作一个数组另一个数组也受到影响,因为他们指向同一地址,如图所示

 

 对象之间的赋值  基本数据类型之间的赋值同理都会导致这样的问题

二.深拷贝

深拷贝不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上,所以对一个对象的修改并不会影响另一个对象。

数组的深拷贝

方法一:for循环

  let arr1 = [1,2,3];
  let arr2 = copyArr(arr1);
  function copyArr(arr){
  	let res=[];
  	for(let i=0,length=arr.length;i<length;i++){
  		res.push(arr[i]);
  	}
  	return res;
  }

方法二   slice()方法  

利用数组自身的方法,slice、

 let arr1 = [1,2,3];
 let arr2 = arr1.slice(0);

方法三  concat()方法  

 let arr1 = [1,2,3];
 let arr2 = arr1.concat();

方法四  扩展运算符

 let arr1 = [1,2,3];
 let [...arr2] = arr1;

 方法五   Array.from

如果参数是一个真正的数组,Array.from会返回一个一模一样的新数组

 let arr1 = [1,2,3];
 let arr2 = Array.from(arr1);

对象的深拷贝

方法一   for循环

   let obj1={count:1,name:'grace',age:1};
    let obj2 = copyObj(obj){
		let res = {};
		for(let key in obj){
  			res[key]=obj[key];
   		}
		return res;
	}

方法二   Json

万能转换器 JSON.parse(JSON.stringify(obj))深拷贝已有对象,它可以深拷贝多层级的,不用担心嵌套问题。

  • JSON.stringfy() 将对象序列化成json对象
  • JSON.parse() 反序列化——将json对象反序列化成js对象

 

 let obj = {
     name: '静茹秋叶'
 }
 console.log('obj: ', obj)
 console.log('json string: ', JSON.stringify(obj))

 let str = JSON.stringify(obj)
 console.log('--------------')
 console.log(str)
 console.log('str to obj: ', JSON.parse(str))

 

 

方法三   扩展运算符

let obj1={count:1,name:'grace',age:1};
let {...obj2} = obj1;

方法四   Object.assign()方法     ES6新增加

 ES6的Object.assign() Object.assign(target, …sources)用于对象的合并,将源对象中的所有可枚举属性,复制到目标对象中,并返回合并后的目标对象。后来的源对象的属性值,将会覆盖它

 let person = {
     name: 'xia',
     age: 25,
     height: 160
 }
 let otherPerson = Object.assign({}, person)
 person.age = 30

 console.log(person)
 console.log(otherPerson)

之前的对象的属性。

 

 

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.指尖舞者

如果帮助到了你,请给点赞助支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值