赞
踩
在JavaScript数据类型可以分为8中:字符串(String
)、数字 (Number
)、布尔 (Boolean
)、空(Null
)、未定义(Undefined
)、Symbol 、Object、BigInt
(任意大的整数)
也可以分为基本数据类型、引用数据类型。
基本数据类型:字符串(String
)、数字 (Number
)、布尔 (Boolean
)、空(Null
)、未定义(Undefined
)、Symbol
-----------存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配。
引用数据类型:Object
【Object是个大类,function函数、array数组、date日期...等都归属于Object】
-----------存放在堆内存中的对象,在栈内存中存的是一个指针,这个指针指向堆内存一个位置。再从堆内存中取得所需的数据。
区别:
深拷贝:在堆内存中重新开辟一个存储空间,完全克隆一个一模一样的对象。
浅拷贝:不在堆内存中重新开辟空间,只复制栈内存中的引用地址。
本质上两个对象(数组)依然指向同一块存储空间。赋值引用类型的时候肯定不能出现浅拷贝的现象,会对原数据产生影响,那么就要进行深拷贝。
常用的深拷贝方式:
1.JSON.stringify():可以深拷贝的数组和对象,但是不能拷贝undefined和Function类型数据,序列化之后会直接丢失。
- var arr = {
- name: 'lemon1号',
- age: 23,
- foods: ['冰淇淋', '水蜜桃'],
- friend: {
- name: '张三',
- age: '22'
- },
- function(){
- console.log("lemon1号的对象")
- }
- }
- //先转为json格式字符,再转回来
- var _arr=JSON.parse(JSON.stringify(arr))
- _arr.name='lemon2号'
- _arr.adress[0]='大西瓜'
- console.log("arr为", arr)
- console.log("_arr为", _arr)
2. 封装一个递归方法:这是最保险最推荐的写法。多数第三方库lodash中的cloneDeep()方法底层也是基于的递归。
- //使用递归实现深拷贝
- function deepClone(obj) {
- //变量先置空
- let newobj = null;
- //obj不能为空,并且是对象或者是数组,null也是object
- if (typeof (obj) == 'object' && obj !== null) {
- newobj = obj instanceof Array ? [] : {};
- //递归进行深度的拷贝
- for (var i in obj) {
- newobj[i] = deepClone(obj[i])
- }
- //如果不是对象直接赋值
- } else {
- newobj = obj;
- }
- return newobj;
- }
-
-
- //------------------- 使用 ----------------------
- let obj = {
- name: 'lemon1号',
- age: null,
- foods: ['冰淇淋', '水蜜桃'],
- friend: {
- name: '张三',
- age: '22'
- },
- function(){
- console.log("lemon1号的对象")
- }
- }
-
- const newObj = deepClone(obj); //这样就完成了一个对象的递归拷贝
- newObj.name = 'lemon2号';
- console.log(newObj);
3.使用扩展运算符:利用了对象的结构赋值特性方法,只能对第一层引用对象进行深拷贝,对于对象中的对象则失效。
- var arr = {
- name: 'lemon1号',
- age: undefined,
- foods: ['冰淇淋', '水蜜桃'],
- friend: {
- name: '张三',
- age: '22'
- },
- function(){
- console.log("lemon1号的对象")
- }
- }
- var _arr={...arr} //这样就完成了一个对象一级拷贝
- _arr.name='lemon2号'
- _arr.friend.name='赵四'
- _arr.foods[0]='大西瓜'
- console.log("arr为", arr)
- console.log("_arr为", _arr)
4.JQuery的extend()方法进行深拷贝:在JQuery构建的项目中,JQuery自身携带的extend()方法可以进行深拷贝。但是对于undefined类型数据,extend()方法之后会直接丢失。两拷贝对象中有相同的属性名时,后者的值也会覆盖前者的值。
- var obj = {
- name: 'lemon1号',
- age: undefined,
- foods: ['冰淇淋', '水蜜桃'],
- friend: {
- name: '张三',
- age: '22'
- },
- function(){
- console.log("lemon1号的对象")
- }
- }
- let _obj= $.extend(true, {}, obj); //这样就完成了一个对象一级拷贝
- _obj.name='lemon2号'
- _obj.friend.name='赵四'
- _obj.foods[0]='大西瓜'
- console.log("obj为", obj)
- console.log("_obj为", _obj)
总结:在JQuery项目中推荐使用extend()函数,其他项目推荐使用封装的递归函数。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。