【javascript】深拷贝和浅拷贝

深拷贝和浅拷贝

在很多实例方法(非静态方法/构造函数原型中的方法)中都体现了深拷贝和浅拷贝【了解原型】。并且深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的。
了解深拷贝和浅拷贝之前,首先要知道内存的空间分布

内存分为5个区:
①栈区stack: 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等
②堆区heap:一般由程序员分配释放, 若程序员不释放,程序结束时可能由系统回收
③全局区(又称静态存储区)(static):全局变量和静态变量的存储是放在一块的
④文字常量区 :常量字符串就是放在这里的, 程序结束后由系统释放;
⑤代码段:存放函数体的二进制代码;

  • 深拷贝
    拷贝值,两个指针指向不同的内存,这两块内存中的数据是一样的
  • 浅拷贝
    拷贝指针,两个指针指向同一块内存
    注意: 赋值传递的是栈区的值
    在这里插入图片描述

方法

  1. 浅拷贝方法
var a = {name:"lily"} var b = a; b === a  //true 
  1. 深拷贝方法

①将json字符串解析成对象JSON.parse()

 var a = {}
 var c = JSON.parse(JSON.stringify(a))
 c === a //测试地址是否相等 false

②{…}es6对象中的扩展运算符,用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中(补充:如果只是一层数组或对象,其元素只是简单类型的元素,那么属于深拷贝)

 let d = { a: 1, b: 2 };
 let  e = { ...d }; // { a: 1, b: 2 }
 d === e//false

如果数组或对象中的元素是引用类型的元素,那么就是浅拷贝

let a = {
	age: 18,
	name: 'a',
	address: {
		city: 'shanghai'
	}
}
let b = {...a};
b.address.city = 'beijing';
console.log(a.address.city);  // beijing浅拷贝

Object.assign(target,sourse)用于对象的合并,第一个参数是目标对象,后面的参数都是源对象,前提是object只有一层的时候是深拷贝(var obj={}),多层时进行浅拷贝(var obj={a:{}})。学习参考:浅拷贝与深拷贝的区别

var obj1 = { a: 1, b: 2 };
var obj2 = Object.assign({},obj1)
obj2 === obj1//false

④函数库lodash
该库提供深拷贝方法_.cloneDeep。

var_ = require('lodash');
var obj1 = {
	a:1,
	b:{f:{g:1}},
	c:[1,2,3]
	}
var obj2 = _.cloneDeep(obj1);
obj1.b.f === obj2.b.f//false

structuredClone

这里分析几个Array的方法,其他实例方法详细了解在MDN

类型方法名简单说明
浅拷贝Array.from()(es6)从一个类似数组或可迭代对象创建一个新的
浅拷贝arr.pop()出栈,将数组末尾的值删除并且返回
浅拷贝arr.shift()出队,将数组开头的值删除并且返回
浅拷贝arr.reverse()数组元素顺序反转,返回反转后的数组
浅拷贝arr.sort()排序,如果没有参数,将会按照字符串(如果是其他类型转换成字符串)的顺序/ASCII码表给数组元素排序,如果参数由比较器函数,则按照比较器函数规则进行排序。
浅拷贝arr.splice(begin,len,item…)可以实现删除,替换,插入元素,begin开始位置,len删除的元素个数,item插入的元素(不限),返回删除元素组成的数组
深拷贝arr.slice(begin,end)从指定数组获取子数组,begin开始位置,end结束位置,裁剪不包含结束位置,end可以省略,截取到数组末尾
深拷贝arr.concat()合并数组,返回合并后的数组
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值