深浅拷贝(es6)

一.直接复制对象问题

 const obj={
            uname:'pink',
            age:18
        };
        const o=obj;
        console.log(o);
        o.age=20;
        console.log(o);
        console.log(obj);

利用o来复制obj对象,改变o对象里面的属性值,obj里面的属性值也会发生改变

二.浅拷贝

  首先浅拷贝和深拷贝只针对引用类型

        浅拷贝:拷贝的是地址

 常见方法:

1.拷贝对象:Object.assgin()/展开运算符{...obj}拷贝对象

2.拷贝数组:Array.prototype.concat()或者〔[...arr]

 const obj={
            uname:'pink',
            age:18,
            family:{
                baby:'小pink'
            }
        }



 const o={}
        Object.assign(o,obj);
        o.age=20;
        o.family.baby='老pink'
        console.log(o);
        console.log(obj);

如果是简单数据类型拷贝值,引用数据类型拷贝的是地址(简单理解:如果是单层对象,没问题,如果有多层就有问题)

直接复制和浅拷贝的区别

直接赋值的方法,只要是对象,都会相互影响,因为是直接拷贝对象栈里面的地址

 浅拷贝如果是一层对象,不相互影响,如果出现多层对象拷贝还会相互影响

浅拷贝怎么理解?

拷贝对象之后,里面的属性值是简单数据类型直接拷贝值

如果属性值是引用数据类型则拷贝的是地址

三.深拷贝

首先浅拷贝和深拷贝只针对引用类型深拷贝:拷贝的是对象,不是地址

        常见方法:

        1.通过递归实现深拷贝

        2.lodash/cloneDeep

        3.通过JSON.stringify()实现

  1.通过递归实现深拷贝

函数递归:

        如果一个函数在内部可以调用其本身,那么这个函数就是递归函数

        简单理解:函数内部自己调用自己,这个函数就是递归函数

        递归函数的作用和循环效果类似

        由于递归很容易发生“栈溢出”错误( stack overflow),所以必须要加退出条件return

const obj={

    uname:'pink',
    age:18,
    hobby:['乒乓球','足球'],
    family:{
        baby:"小pink"
    }
}
const o={}
// console.log(obj["uname"]);
// 拷贝函数
function deepCopy(newObj,oldObj){
    for(let k in oldObj){
        //处理数组问题
        if(oldObj[k] instanceof Array){
            //newObj[]接手[]
            //oldObj[k]['乒乓','足球']
         newObj[k]=[];
         deepCopy(newObj[k],oldObj[k]);
        }else if(oldObj[k] instanceof Object){
            newObj[k]={};
            deepCopy(newObj[k],oldObj[k]);
        } else{
    // k属性名 unmae  oldObj[k]属性值  18
    ///newObj[k ]=== o.uname
             newObj[k]=oldObj[k];
        }
       
    }

}
deepCopy(o,obj)//函数调用  两个参数 o 新对象  obj旧对象
console.log(o);

注意:先递归数组在递归对象

2.js库lodash里面cloneDeep内部实现了深拷贝

<!-- 先引用 -->
    <script src="./lodash.min.js"></script>
  const obj = {

            uname: 'pink',
            age: 18,
            hobby: ['乒乓球', '足球'],
            family: {
                baby: "小pink"
            }
        }

     const o= _.cloneDeep(obj);
     console.log(o);
     o.family.baby="老pink";
     console.log(obj);

3.通过JSON.stringify()实现

 const obj = {

            uname: 'pink',
            age: 18,
            hobby: ['乒乓球', '足球'],
            family: {
                baby: "小pink"
            }
        }

        // 把对象转换未JSON字符串
        // console.log( JSON.stringify(obj) );
        // 把字符串转换成对象
       const o= JSON.parse(JSON.stringify(obj))
       console.log(o);
      o.family.baby="123";
      console.log(obj);

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
writable是ES6中的一个属性,用于定义对象的属性是否可被赋值修改。当将一个属性定义为writable时,这个属性可以被修改,即可以通过赋值运算符改变该属性的值。 在ES6之前,对象的属性默认都是可写的,即默认可被修改。但是ES6引入了一些新的特性来优化对象的属性定义与访问。其中一个特性就是writable属性。通过将属性定义为不可写,可以避免在修改属性时出现意外的情况。 在ES6中,我们可以使用Object.defineProperty()方法来定义对象的属性,并设置属性的可写性。该方法接受三个参数:需要定义属性的对象、属性名和一个描述符对象。描述符对象中的writable属性,用于指定属性是否可写。 例如,我们定义了一个person对象,该对象有一个名为name的属性。我们可以选择性地将该属性定义为不可写,以确保在运行时不会修改对象的名称: ```javascript const person = {}; Object.defineProperty(person, 'name', { value: 'John', writable: false, // 将属性设置为不可写 }); person.name = 'Jane'; // 尝试修改属性的值,但会被忽略 console.log(person.name); // 输出: John ``` 通过上述代码,我们可以看到无论我们如何尝试修改person对象的name属性,最终结果都是保持不变。这是因为在定义属性时,我们将其设置为不可写。这样做可以确保我们在代码中意外地修改属性的值。 在使用ES6的可写性特性时,需要根据实际需求来决定是否将属性定义为可写。在某些情况下,将属性定义为只读是非常有用的,以确保数据的稳定性和完整性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值