Js(深拷贝 浅拷贝 递归)

一.浅深拷贝

浅拷贝:只能拷贝一层,如果是简单类型,拷贝的是值,如果是引用类型拷贝的是地址.

  const obj1 = {
            uname: '张三',
            age: 18,
            gender: '男',
            gfs: ['凤姐', '芙蓉姐姐', '黄蓉'],
            wife: {
                w1: '蔡徐坤',
                w2: 'ikun'
            }
        }
        // 浅拷贝:只拷贝对象的第一层 如果第一层有引用类型 拷贝的是内存引用地址,如果是简单地址,拷贝的是值
        // 使用展开运算符,可以是浅拷贝
        // const obj2 = { ...obj1 }
        // obj2.uname = '王五'
        // obj2.gfs[0] ='小王'
        //     console.log(obj2)
        // 使用Object.assign 将一个对象拷贝到另一个对象
        Object.assign(obj2, obj1)
        obj2.uname = '王五'
         obj2.gfs[0] ='小王'

深拷贝:可以拷贝多层,不管是引用类型还是简单类型,拷贝的都是值.

  const obj1 = {
            uname: '张三',
            age: 18,
            gender: '男',
            gfs: ['凤姐', '芙蓉姐姐', '黄蓉'],
            wife: {
                w1: '蔡徐坤',
                w2: 'ikun'
            }
        }
        // 创建一个空对象
        const obj2 = {}
        // 封装函数
        function deepCopy(newObject, oldObject) {
            // 遍历旧对象
            // debuggerm   断点调试
            for (let k in oldObject) {
                // 获取旧对象的值赋给item变量
                const item = oldObject[k]
                //   判断item是不是数组
                if (item instanceof Array) {
                    // 对数组
                    // 给newObject添加属性 但属性的值添加一个空的数组
                    newObject[k] = []
                    deepCopy(newObject[k], item)
                } else if (item instanceof Object) {
                    //    对对象
                    // 给newObject添加属性 但属性的值添加一个空的对象
                    newObject[k] = {}
                    deepCopy(newObject[k], item)
                } else {
                    // 将old对象属性值 赋值给新对像
                    newObject[k] = item
                }
            }
        }
        deepCopy(obj2, obj1)
        obj2['gfs'][0]='嘿嘿嘿'

实现深拷贝的方法: 1.使用递归   2.利用JSON字符串    3.引用lodashi的JS文件

  const obj1 = {
            uname: '张三',
            age: 18,
            gender: '男',
            gfs: ['凤姐', '芙蓉姐姐', '黄蓉'],
            wife: {
                w1: '蔡徐坤',
                w2: 'ikun'
            }
        }
        // 先将 对象转成json字符串
        const str = JSON.stringify(obj1)
        // 将json字符串转换成js对象
        const obj2 = JSON.parse(str)
        obj2['gfs'][0] = '王五'

二.异常处理

  • throw抛异常

     抛出异常使用throw关键字,会中止程序. Error对象配合throw使用

  function fn(x, y) {
            if (!x || !y) {
                throw new Error('没有传参')
            }
            return x + y
        }
        const res = fn()
  • try/catch捕获异常

    捕获异常使用 try catch try关键字   利用catch的参数调用信息

 <button class="id">按钮</button>
    <script>
        try {
            const but = document.querySelector('id')
            but.innerHTML = '老刘'
        } catch (error) {
            
            throw new Error('err.message')
        }
        finally {
            console.log('hello')
        }
    </script>
  • debugger(断点调试)

三.处理this

普通函数this指向:

  • 谁调用,this指向谁
  • 构造函数内this指向实例化对象
  • 普通函数内this指向window

箭头函数this指向:

  • 箭头函数内没有this
  • 会沿用当前函数的上一级函数的this

改变函数this指向:

call Bind  Apply 区别:

  •  相同点:他们都是改变函数的this指向.
  •  不同点:Call第一个参数是改变函数this指向,第二个参数可以是参数列表
  •  Apply:第一个参数是改变函数this指向,第二个参数是数组
  •  Bind:函数不会调用,会返回一个新的函数,第二个参数可以是多个
   function fn(x, y) {
            console.log(this, x, y)
        }
        const obj = {
            uname: '张三'
        }
        //相同点:call()和apply() 都可以调用函数,都可以改变函数的this指向
        //不同点:传递的参数个数不一样,call()可以传递多个参数,而apply()只能传递两个参数  第一个参数是需要改变函数里面的对象  第二个参数必须是数组
        fn.apply(obj, [10, 20])
 const arr = [10, 20, 30, 40, 50]
        // 利用apply()来 求数组的最大值
        // apply(可以调用函数)
        // apply()多用于数组有关系的
        const res = Math.max.apply(Math, arr)
        console.log(res)  

 

 /*  bind call apply  三者区别:
         相同点:都可以改变函数的this指向
         不同点:1.bind不能调用函数,会返回一个新的函数 call和apply可以调用函数
                2.call 第一个形参用于改变函数的this指向,其他的形参 可以是 参数列表
                3.bind第一个形参是用于改变函数的this指向,其他的参数可以是参数列表
                4.apply的形参只有两个 第一个是用与改变函数的this指向,第二个形参是一个数组
         
        */
        function f(x, y) {
            console.log(this, x, y)
        }
        const obj = {
            uname: 'zs',
            age: 18
        }
        const res = f.bind(obj, 10, 20)
        res()

四.递归

递归:在函数里调用自己

作用:实现浅拷贝,深拷贝,遍历Dom树

<script>
        function f(n) {
            console.log(n)
            n = n - 2
            if (n > 0) {
                f(n)
            }
            console.log(n)
        }
        f(10)
    </script>
 
//悲波拉锲数列
 // 已知第一项和第二项数字是1
        // 第一项   第二项  第三项   第四项  第五项  第六项
        //    1       1       2       3       5      8
        // 我们想过知道数组的第六项和的值
        // 第四项和第五项的和
        // 第四项的=第二项+第三项
        function f(n) {
            if (n === 1 || n === 2) {
                return 1
            } else {
                // return 前一项 +前两项
                return f(n - 1) + f(n - 2)
            }
        }
        const res = f(10)
        console.log(res)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值