ES6:深拷贝、浅拷贝、闭包以及解构赋值

浅拷贝与深拷贝

栈内存和堆内存

  • 栈内存:简单数据类型 string,number,boolean,null,undefined
  • 堆内存:复杂数据类型 object,array....

注意:

  • 浅拷贝就是将引用数据类型 在栈内存中的引用地址拷贝一份 指向的还是堆空间的旧数据数据
  • 深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象 

1.浅拷贝

    //    浅拷贝
let arr1 = ["北京", "上海", "广州",["白云区","黄埔区"]]
// arr1赋值给arr2  
// *****这里只是将数组的引用的地址拷贝了一份赋值给了arr2
let arr2 = arr1

arr2[0] = "beijing"
console.log("arr2", arr2)
console.log("arr1", arr1)

 

注意:

因为两份地址指向的是同一数据,所以当arr2改变数组的内容时,arr1打印的结果也会发生改变。

 2.深拷贝

利用for in循环 进行深拷贝

  //    深拷贝
let arr1 = ["北京", "上海", "广州",{uname:"小明",age:21}]
let arr2 = []
// 先通过for in 循环数组 能够拿到数组中的每一项
// 注意:因为 for in 循环 既可以循环数组也可以循环兑对象 
for (k in arr1) {
// 由于数据结构是数组嵌套对象  所以需要进行对数据类型进行判断
if (arr1[k] instanceof Array) {
    //如果数组里的数据还有数组就在数组里定义一个空数组
    arr2[k] = []
    // 继续进行二次循环将数组的值循环赋值给空数组
    for (var m in arr1[k]) {
        arr2[k][m] = arr1[k][m]
    }
    // 如果是对象的话同理 进行循环
} else if (arr1[k] instanceof Object) {
    //对象
    arr2[k] = {}
    for (n in arr1[k]) {
        arr2[k][n] = arr1[k][n]
    }
} else {
    //这里是简单数据类型  可以直接赋值
    arr2[k] = arr1[k]
}
}
// 打印结果
arr2[3].uname = "修改测试"
// 同打印两个数据进行比较
console.log("arr2", arr2,"arr1", arr1)

注意

因为深拷贝实在堆内存中开辟了新的空间,把原数据拷贝了这个新开辟的空间中,所以两个数组互不干涉,新数据修改对原数据没有影响。

利用递归实现深拷贝

递归就是自己调用自己

var obj1 = {
      uname: "小明",
      age: 21,
      school: {
        name: "清华大学",
        address: "海淀",
        subSchool: { name: "清华美院", address: "五道口" }
      },
      hobby: ["学习", "跑步", "吃饭"]
    }

    //调用
    var obj2 = {}
    deepCopy(obj2, obj1)

    //定义
    function deepCopy(obj2, obj1) {
      for (k in obj1) {
        if (obj1[k] instanceof Array) {
          obj2[k] = []
          deepCopy(obj2[k], obj1[k])
        } else if (obj1[k] instanceof Object) {
          obj2[k] = {}
          deepCopy(obj2[k], obj1[k])
        } else {
          //简单数据类型
          obj2[k] = obj1[k]
        }
      }
    }

    obj2.school.name = "qinghuadaxue";
    console.log(obj2,obj1);

 

利用JSON.parse(JOSN.stringify()) 实现暴力深拷贝

先利用JSON.stringify 将对象转为JOSN字符串进行拷贝,在l利用JSON.parse()方法转换为对象

 var obj1 = {
        name: "小明",
        age: 21,
        height: 170,
        school: {
            name: "清华大学",
            addres: "北京"
        }
    }
    var obj2 = JSON.parse(JSON.stringify(obj1))
    obj2.school.name = "清华美术学院"
    //    可以发现修改了obj2,不影响obj1
    console.log("obj5", obj2);
    console.log("obj3", obj1);

 

 闭包

闭包就是 能够读取其他函数内部变量的函数 

           函数嵌套函数 当内部函数访问外部函数内部的变量时,就会形成闭包

案例

 点击元素改打印元素中的内容

<body>
    <ul>
        <li>八戒</li>
        <li>悟空</li>
        <li>唐僧</li>
        <li>沙僧</li>
    </ul>
</body>
<script>
    var list = document.querySelectorAll("li")
    // console.log(list)

    /*利用闭包,实现列表内容的点击获取*/
    for (var i = 0; i < list.length; i++) {

        (function (i) {

            list[i].onclick = function () {
                console.log(list[i].innerHTML)
            }

        })(i)

    }
</script>

 

var,const,let关键字

  • 暂时性死区

    使用ES6的变量声明方法(letconstclass…)声明的变量,不可在声明前使用访问,否则会进行显式报错ES6变量声明前的代码区域,称为 “暂时性死区”

    let x=1;
    let foo=function(){
        //暂时性死区
    	console.log(x)
    	let x=2;
    }
    foo()

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值