JS进阶——深浅拷贝、异常处理、this指向、防抖节流

本文介绍了JavaScript中的深拷贝和浅拷贝概念,包括展开运算符和Object.assign方法的浅拷贝以及通过JSON.stringify实现的深拷贝。此外,还讲解了异常处理的throw和try/catch机制,以及在不同场景下如何改变this的指向,如call、apply和bind方法。最后讨论了性能优化中的防抖和节流技术,用于限制函数的执行频率。
摘要由CSDN通过智能技术生成

深浅拷贝

深浅拷贝只针对引用类型。

浅拷贝

浅拷贝拷贝的是地址
单层对象的拷贝,多层对象使用这种拷贝方法就会出现问题。

 <script>
        //对象的浅拷贝
        const obj = {
            name: 'name',
            age: 18
        }
        // 通过展开运算符{...}拷贝对象
        const o = { ...obj }
        o.age = 20
        console.log(o);

        //通过Object.assgin方法拷贝对象
        const r = {}
        Object.assign(r, obj)
        r.age = 19
        console.log(r)

        // obj中的内容将不会改变
        console.log(obj)

        // 数组的浅拷贝
        const arr = [1, 2, 3]
        // 通过展开运算符拷贝数组
        const a = [...arr]
        a.push(1)
        console.log(a)
        // 通过concat方法拷贝数组
        const b = [].concat(arr)
        b.pop(1)
        console.log(b)

        console.log(arr)



    </script>

深拷贝

深拷贝拷贝的是对象,不是地址。
深拷贝怎么实现:深拷贝可以实现拷贝出的新对象不会影响旧对象,实现深拷贝需要用到函数递归,普通拷贝直接赋值即可,如果遇到数组再次调用递归函数,如果遇到对象形式再次调用递归函数,如果有数组又有对象,那么先数组后对象,因为数组也是一种对象。
常见方法:

  • 通过递归实现深拷贝

  • lodash/cloneDeep
    _.cloneDeep(obj)

  • 通过JSON.stringify()实现
    将对象转换成JSON 字符串,然后再转换成JSON对象。

<script>
    const obj = {
        name: 'name',
        age: 18,

        family: {
            mother: 'lxy',
        }
    }

    const o = JSON.parse(JSON.stringify(obj))
    o.family.mother = 'ren'
    console.log(o)
    console.log(obj)
</script>

异常处理

预估代码执行过程中可能发生的错误。

throw抛异常

抛出异常信息,程序终止执行,Error对象配合throw使用

<script>
    function sum(a, b) {
        if (!a || !b) {
            throw new Error('没有参数传递过来')
        }
        return a + b
    }
    console.log(sum());
</script>

try/catch捕获异常

捕获错误信息(浏览器提供的错误信息),不中断程序,如果需要中断程序,就用return。
将预估可能发生错误的代码写到try中,如果发生了错误catch就会拦截下来,并打印错误信息,finally不管是否有错误都会执行。

<p>123</p>
<script>
    function fn() {
        try {
            document.querySelector('.p').style.color = 'pink'
        } catch (err) { //参数err
            console.log(err.message);  //打印错误信息
            throw new Error('选择器错误')
            return   //中断程序,不会打印11
        }
        finally {   //肯定会执行的代码写在finally中
            console.log(22)
        }
        console.log(11)

    }
    fn()
</script>

debugger

相当于一个断点。

处理this

this指向

普通函数:谁调用就指向谁。普通函数的严格模式下指向undefined。
箭头函数:箭头函数中没有this,要向外层作用域中一层一层的查找this,直到有this的定义。
构造函数、原型函数(原型对象)、DOM事件函数(点击事件等)最好不要用箭头函数。

改变this

  • call()
fun.call(thisArg,arg1,arg2,...)

thisArg:在fun函数运行时指定的this值。
arg:普通的参数

  <script>
        //call方法改变this的指向
        const obj = {
            name: 'lxy'
        }
        function fn(x, y) {
            console.log(this); //本来指向window,通过call改变了指向obj
        }
        fn.call(obj, 1, 2)  //fn.call调用函数同时改变this指向
        //obj给了this 实参 1传给x,2传给y
    </script>
  • apply()
fun.apply(thisArg,[argsArray])

thisArg:在fun函数运行时指定的this值。
argsArray:传递的值,必须包含在数组里
返回值就是函数的返回值,因为他就是调用函数
因此apply主要和数组有关系,比如使用Math.max()求数组最大值

  • bind()
    bind方法不会调用函数(而apply和call都会立即调用函数),但是能改变函数内部的this指向。
fun.bind(thisArg,arg1,arg2,...)

thisArg:在fun函数运行时指定的this值。
arg:传递的其他参数
返回由指定的this值和初始化参数改造的原函数拷贝(新函数)
因此当我们只是想改变this指向,而不想调用这个函数的时候,可以使用bind,比如改变定时器内部的this指向。

 const obj = {
            name: 'pink'
        }

        function fn() {
            console.log(this); //本来指向window,通过call改变了指向obj
        }

        const fun = fn.bind(obj) //bind不会调用函数,返回一个新函数,指向obj的新函数
        fun()  //返回的是函数,所以要调用

改变this指向方法的区别

在这里插入图片描述

性能优化

防抖debounce

防抖:单位时间内,频繁触发事件,只执行最后一次

节流throttle

防抖:单位时间内,频繁触发事件,只执行一次

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值