您现在的位置是:群英 > 开发技术 > web开发
深拷贝和浅拷贝的方式,如何在JS中实现
Admin发表于 2022-05-17 17:22:44697 次浏览
这篇文章给大家分享的是“深拷贝和浅拷贝的方式,如何在JS中实现”,文中的讲解内容简单清晰,对大家学习和理解有一定的参考价值和帮助,有这方面学习需要的朋友,接下来就跟随小编一起学习一下“深拷贝和浅拷贝的方式,如何在JS中实现”吧。



说道数据拷贝就离不开数据类型,在js中数据类型分为基本类型和引用类型 基本类型:

number, boolean,string,symbol,bigint,undefined,null

引用类型:

object 以及一些标准内置对象 array、regexp、string、map、set..

一. 基本类型数据拷贝

基本类型数据都是值类型,存储在栈内存中,每次赋值都是一次复制的过程

	var a = 12;
	var b = a;

二. 引用类型数据拷贝

1、浅拷贝

只拷贝对象的一层数据,再深处层次的引用类型value将只会拷贝引用 实现方式:

1.object.assign() 和 es6的拓展运算符

通常我们用 object.assign() 方法来实现浅拷贝。 object.assign()用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。

	let aa = {
		a: undefined, 
		func: function(){console.log(1)}, 
		b:2, 
		c: {x: 'xxx', xx: undefined},
		d: null,
		e: bigint(100),
		f: symbol('s')
	}
	let bb = object.assign({}, aa) //  或者 let bb = {...aa}
	aa.c.x = 111
	console.log(bb)
	// 第一层拷贝,遇到引用类型的值就会只拷贝引用
	// {
	//     a: undefined,
	//     func: [function: func],
	//     b: 2,
	//     c: { x: 111, xx: undefined },
	//     d: null,
	//     e: 100n,
	//     f: symbol(s)
	// }

2.object.create

object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。object.create(proto,[propertiesobject])接收两个参数一个是新创建对象的__proto__, 一个属性列表

	let aa = {
		a: undefined, 
		func: function(){console.log(1)}, 
		b:2, 
		c: {x: 'xxx', xx: undefined},
	}
	let bb = object.create(aa, object.getownpropertydescriptors(aa))
	aa.c.x = 111
	console.log(bb)
	// 第一层拷贝,遇到引用类型的值就会只拷贝引用
	// {
	//     a: undefined,
	//     func: [function: func],
	//     b: 2,
	//     c: { x: 111, xx: undefined },
	// }

2、深拷贝

在拷贝一个对象的时候为了避免修改对数据造成的影响,必须使用深拷贝。

实现方式:

1、 通过json.stringify()

	var a = {a:1, b: 2}
    var b = json.stringify(a);
    a.a = 'a'
    console.log(a, b) // { a: 'a', b: 2 } {"a":1,"b":2}

json.stringify()进行深拷贝有弊端: 忽略value为function, undefind, symbol, 并且在序列化bigint时会抛出语法错误:typeerror: do not know how to serialize a bigint

// 序列化function, undefind, symbol,忽略--------------------------------------------------------
	var obj = {
		a:function(){}, 
		b: undefined, 
		c: null, 
		d: symbol('s'), 
	}
    var objcopyed = json.stringify(obj);
    
    console.log("a:", a) 
    // obj: { a: [function: a], b: undefined, c: null, d: symbol(s) }
    console.log("objcopyed:", objcopyed) 
    // objcopyed: {"c":null}
// 序列化bigint抛出错误--------------------------------------------------------
    var obj = {
    	a: 1,
    	e: bigint(9007199254740991)
    }
    var objcopyed = json.stringify(obj); // typeerror: do not know how to serialize a bigint

2、递归实现

const deepcopy = (obj) => {
	// 优化 把值类型复制方放到这里可以少一次deepcopy调用
	// if(!obj || typeof obj !== 'object') throw new error("请传入非空对象")
    if(!obj || typeof obj !== 'object') return obj
    let result = {}
    if (object.prototype.tostring.call(obj).indexof('array') > 0) {
        result = []
    }
    // 另一种循环方式
    // for (let key in obj) {
    //     if (obj.hasownproperty(key)) {
    //        result[key] = deepclone(obj[key]) 
    //     }
    // }
    object.keys(obj).foreach(key => {
    	// 优化 把值类型复制方放到这里可以少一次deepcopy调用
    	// if (obj[key] && typeof obj[key] === 'object') {
        //     result[key] = deepcopy(obj[key])
        // }else{
        //     result[key] = obj[key]
        // }
        result[key] = deepcopy(obj[key])
    });
    return result
}

let aa = {
	a: undefined, 
	func: function(){console.log(1)}, 
	b:2, 
	c: {x: 'xxx', xx: undefined},
	d: null,
	e: bigint(100),
	f: symbol('s')
}
let bb = deepcopy(aa)
aa.c.x = 123
aa.func = {}
console.log("aa", aa)
console.log("bb", bb)
// aa {
//     a: undefined,
//     func: {},
//     b: 2,
//     c: { x: 123, xx: undefined },
//     d: null,
//     e: 100n,
//     f: symbol(s)
//  }

// bb {
//     a: undefined,
//     func: [function: func],
//     b: 2,
//     c: { x: 'xxx', xx: undefined },
//     d: null,
//     e: 100n,
//     f: symbol(s)
// }

手写深拷贝等这些工具方法,在实际生产中99.99%不会用到,毕竟有lodash、underscore这些方便的工具库呢


以上就是关于“深拷贝和浅拷贝的方式,如何在JS中实现”的相关知识,感谢各位的阅读,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注群英网络,小编每天都会为大家更新不同的知识。

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

相关信息推荐
2022-01-07 18:30:13 
摘要:小程序打不开了是啥缘故,怎样解决?一般来说如果微信小程序大家不开了,可能是缓存、版本、手机、网络或是小程序本身等等这些因素造成的,那么我们应怎样解决这个问题呢?下面我们就具体了解看看。
2022-10-11 09:25:49 
摘要:这篇文章主要介绍了一文探索Java文件读写更高效方式,文章围绕主题展开详细的内容介绍,具有一定的参考价值需要的小伙伴可以参考一下
2022-06-21 17:12:26 
摘要:本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于数字类型的相关内容,JavaScript中存在两种表示数字的类型:Number和BigInt类型,下面一起来看一下,希望对大家有帮助。
云活动
推荐内容
热门关键词
热门信息
群英网络助力开启安全的云计算之旅
立即注册,领取新人大礼包
  • 联系我们
  • 24小时售后:4006784567
  • 24小时TEL :0668-2555666
  • 售前咨询TEL:400-678-4567

  • 官方微信

    官方微信
Copyright  ©  QY  Network  Company  Ltd. All  Rights  Reserved. 2003-2019  群英网络  版权所有   茂名市群英网络有限公司
增值电信经营许可证 : B1.B2-20140078   粤ICP备09006778号
免费拨打  400-678-4567
免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
微信公众号
返回顶部
返回顶部 返回顶部