前端中的深拷贝和浅拷贝及相应注意事项

3 篇文章 0 订阅

 讲到前端中的深拷贝与浅拷贝之前需要先简单了解下js中的堆与栈:

1、堆和栈都是运行时内存分配的一个数据区

2、js的变量类型有哪些

3、浅拷贝和深拷贝

4、有属性对象的对象不能用ES6提供的Object.assign()以及扩展运算符(...)

5、有属性对象的对象怎么深拷贝

6、多维数组如何深拷贝


讲到前端中的深拷贝与浅拷贝之前需要先简单了解下js中的堆与栈:

1、堆和栈都是运行时内存分配的一个数据区

(1)堆(heap)

堆(heap)用于复杂数据类型(引用类型)分配空间,例如数组对象、object对象;
它是运行时动态分配内存的,因此存取速度较慢

(2)栈(stack) 

栈(stack)中主要存放一些(基本类型)的变量和对象的引用,(包含池、池存放常量),
其优势是存取速度比堆要快,并且栈内的数据可以共享,但缺点是存在栈中的数据大小
与生存期必须是确定的,缺乏灵活性

2、js的变量类型有哪些

(1)值类型(基本类型):字符串(string)、数值(number)、布尔值(boolean)、undefined、null、symbol(这6种基本数据类型是按值访问的,因为可以操作保存在变量中的实际的值)(ECMAScript 2016新增了一种基本数据类型:symbol)

  • 值类型复制时复制的是值本身

  • 保存在栈中,占用空间固定,随着方法运行结束,方法内定义的变量会随之销毁

  • 使用typeof检测数据类型

(2)引用类型:对象(Object)、数组(Array)、函数(Function)、包括有正则表达式

  • 引用类型复制时复制的是指向对象的一个指针

  • 使用 instanceof 检测数据类型

  • 使用new()方法构造出的对象是引用型

3、浅拷贝和深拷贝

(1)浅拷贝:对地址的引用,只要我们修改了一个拷贝后的(数组、对象等),那么原(数组、对象等)也会改变。

var obj = {
            name:"前端",
            age:"10"
        }
        var oldObj = obj;
        obj.name = "html + css + js";
        console.log(oldObj); //{name: "html + css + js", age: "10"}

(2)深拷贝:属于创建了一个新的内存空间。 他们不在会共用同一个内存空间。是两个完全独立的对象或数组。

var obj = {
            name:"前端",
            age:"10"
        }
        var oldObj = {...obj};
        obj.name = "html + css + js";
        console.log(oldObj); //{name: "前端", age: "10"}

SE6提供的浅拷贝的方法Object.assign()以及扩展运算符(...); 

如:若被拷贝的对象中有属性对象,则依然会影响到被拷贝对象。

var obj = {
            smallObj:{name:"obj",
                 age:"10"   
                            },
            name:"前端",
            age:"10"
        }
        var oldObj = {...obj};
        oldObj.smallObj.name = "html + css + js";
        console.log(obj);

打印为: 

4、有属性对象的对象不能用ES6提供的Object.assign()以及扩展运算符(...)

用扩展运算符对数组或者对象进行拷贝时,只能扩展和拷贝第一层的值,对于第二层极其以后的值,扩展运算符将不能对其进行打散扩展,也不能对其进行拷贝,即拷贝后和拷贝前第二层中的对象或者数组仍然引用的是同一个地址,其中一方改变,另一方也跟着改变

5、有属性对象的对象怎么深拷贝

封装的方法: 

function deepClone(obj) {
    var newObj = Array.isArray(obj) === true ? [] : {};
    for (let key in obj) {
        if (typeof obj[key] == 'object') {
            newObj[key] = deepClone(obj[key]);
        } else {
            newObj[key] = obj[key];
        }
    }
    return newObj;
}
var formItem = {
          version:"版本号",
          corporationBasicInfo:{
              "corporationName":"法人姓名",
              "corporationIdCardType":"法人证件类型",
              "corporationIdCardNo":"法人证件号码",
              
          }
     }
let b = deepClone(formItem);

对象b的打印:

改变对象 b 中的某个属性对象的属性值 

b.corporationBasicInfo.corporationIdCardNo = 1
console.log(b)

 对象 b 的打印:

console.log(formItem)

 被拷贝对象 formItem 的打印:

或者利用json数据和json字符串之间的转换

var formItem = {
        version:"版本号",
        corporationBasicInfo:{
           "corporationName":"法人姓名",
           "corporationIdCardType":"法人证件类型",
           "corporationIdCardNo":"法人证件号码"
        }
   }
var str = JSON.stringify(formItem);
var pbj = JSON.parse(str);
formItem.corporationBasicInfo.corporationIdCardNo=1;
console.log(formItem);
console.log(pbj);

打印为:

6、多维数组如何深拷贝

function deepcopy(obj) {
        var out = [];
        for (let i=0; i < obj.length; i++) {
           if (obj[i] instanceof Array){
               out[i] = deepcopy(obj[i]);
           }else{
               out[i] = obj[i];
                 } 
        }
       return out;
}
let a = [1, 2, 3, 4, 5, 6, [1, 2, 3]];
let b = deepcopy(a);
b[6][0] = 100
console.log(b);
console.log(a);

打印为:

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值