我们提供安全,免费的手游软件下载!

安卓手机游戏下载_安卓手机软件下载_安卓手机应用免费下载-先锋下载

当前位置: 主页 > 软件教程 > 软件教程

JavaScript深浅拷贝详解

来源:网络 更新时间:2024-07-14 04:31:24

深拷贝和浅拷贝是JavaScript中处理对象和数据复制操作的两种方式。在探讨深浅拷贝之前,我们需要先了解JavaScript中的两种数据类型:

基本数据类型包括String、Number、Object、Boolean、null、undefined和symbol(ES6+)。

而引用数据类型则包括Object(如function、Array和正则表达式等都是对象)。

在JavaScript中,基本数据类型存储在栈中,而引用类型存储在堆内存中的对象。基本数据类型按值存放,可以直接按值访问。引用类型存储在堆内存中,栈内存中保存对堆内存中对象的引用地址。

浅拷贝

什么是浅拷贝

浅拷贝是创建一个新的数据,该数据包含原始数据属性的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的是内存地址,因此浅拷贝只拷贝一层,深层次的引用类型会共享内存地址。

以下用一张图解释了浅拷贝:

浅拷贝的实现方法

assign

var obj = {
	age: 18,
	person: {
		name1: 'fx',
		name2: 'xka'
	},
	list:['hhh','666'],
	love: function () {
		console.log('嘿嘿')
	}
}
var newObj = Object.assign({}, obj);
// 因为是浅拷贝,所以只拷贝了基本类型的,引用类型还是共享内存地址的,即改变obj的引用类型的内容,newObj里面的引用类型的值也随之改变
obj.person.name1='xxx'
obj.list[0]='xxx'
console.log(newObj.person.name1) //xxx

slice

const fxArr = ["One", {
	name: "Two",
	age: 20
}, "Three"]
const fxArrs = fxArr.slice(0,)
fxArr[1].name = "four";
console.log(fxArrs[1].name) //four

concat

const fxArr = ["One", {
	name: "Two",
	age: 20
}, "Three"]
const fxArrs = fxArr.concat()
fxArr[1].name = "four";
console.log(fxArrs[1].name) //four

拓展运算符

const fxArr = ["One", {
	name: "Two",
	age: 20
}, "Three"]
const fxArrs = [...fxArr]
fxArr[1].name = "four";
console.log(fxArrs[1].name) //four

深拷贝

什么是深拷贝

深拷贝会开辟一个新的栈空间,两个对象完全相同,但对应不同的地址。修改一个对象的属性不会改变另一个对象的属性。

以下用一张图解释了深拷贝:

深拷贝的实现方法

JSON.parse(常用)

var obj = {
	age: 18,
	person: {
		name1: 'fx',
		name2: 'xka'
	},
	list:['hhh','666'],
	love: function () {
		console.log('嘿嘿')
	}
}

const obj2=JSON.parse(JSON.stringify(obj));
obj.person.name1='6666'
console.log(obj2.person.name1) //fx

JSON.parse是经常使用的方法。然而,之前听说过的lodash的cloneDeep和jq的extend我都没有使用过。JSON.parse的一个缺点是它会忽略包含undefined、function和symbol的数据。这也是一个优点,因为可以利用其特性排除undefined等数据,获取干净的数据。另一个缺点是在处理大型数据时可能存在性能问题。

手写实现深浅拷贝

浅拷贝

function clone(object){
	const newObj={}
	for(let proto in object){
		if(object.hasOwnProperty(proto)){
			newObj[proto]= object[proto]
		}
	}
	return newObj
}
var obj = {
	age: 18,
	person: {
		name1: 'fx',
		name2: 'xka'
	},
	list:['hhh','666'],
	love: function () {
		console.log('嘿嘿')
	}
}

const obj1=clone(obj)
console.log(obj)
console.log(obj1)

深拷贝

// 手写深拷贝
function deepClone(obj, hash = new WeakMap()) {
	// 数据过滤
	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 obj;
	if (hash.get(obj)) return hash.get(obj);
	let cloneObj = new obj.constructor();
	hash.set(obj, cloneObj);
	for (let key in obj) {
		if (obj.hasOwnProperty(key)) {
			cloneObj[key] = deepClone(obj[key], hash);
		}
	}
	return cloneObj;
}
var obj = {
	age: 18,
	person: {
		name1: 'fx',
		name2: 'xka'
	},
	list:['hhh','666'],
	love: function () {
		console.log('嘿嘿')
	}
}


const obj2 = deepClone(obj) // 深拷贝
const obj3 = Object.assign({}, obj) // 浅拷贝
const obj4 = clone(obj) // 浅拷贝
obj.person.name1 = 'hhh';
console.log(obj2.person.name1) //fx
console.log(obj3.person.name1) //hhh
console.log(obj4.person.name1) //hhh

以上内容为个人学习整理,水平有限,如有错误之处,敬请指正。若觉得不错,请点击推荐和关注!谢谢~๑•́₃•̀๑ [鲜花][鲜花][鲜花]