JavaScript入门到精通三十二(深拷贝、浅拷贝、递归函数)

一.浅拷贝

拷贝的是地址

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

2.拷贝数组:Array.prototype.concat() 或者** ...arr **

javascript 复制代码
<body>
  <script>
    const obj = {
      name:'张三',
      age:18,
    }
    console.log(obj);
    // 使用对象的引用类型特性,修改a,也会修改obj的属性
    const a = obj
    a.name = '李四'
    console.log(a);
    console.log(obj);
  </script>
</body>
javascript 复制代码
<body>
  <script>
    const obj = {
      name:'张三',
      age:18,
    }
    console.log(obj);
    // 使用对象的浅拷贝方法,不会改变原对象的属性值
    const a = { ...obj }
    a.age = 20
    console.log(a);
    console.log(obj);
  </script>
</body>
javascript 复制代码
<body>
  <script>
    const obj = {
      name:'张三',
      age:18,
    }
    console.log(obj);
    // 浅拷贝第二种方法
    const a = {}
    Object.assign(a, obj)
    a.age = 20
    console.log(a);
    console.log(obj);
  </script>
</body>

如果是简单数据类型拷贝值,引用数据类型拷贝的是地址

简单理解:如果是单层对象,没问题,如果有多层就有问题

javascript 复制代码
<body>
  <script>
    const obj = {
      name:'张三',
      age:18,
      family : {
        name:'李四'
      }
    }
    console.log(obj);
    const a = {}
    Object.assign(a, obj)
    a.family.name = '王五'
    console.log(a);
    console.log(obj);
  </script>
</body>

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

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

二.深拷贝

拷贝的是对象,不是地址

1.通过递归函数实现深拷贝

2.lodash/cloneDeep

3.通过**JSON.stringify()**实现

通过递归函数实现深拷贝:

javascript 复制代码
<body>
  <script>
    const obj = {
      name:'张三',
      age:18,
      habby:['篮球','足球']
    }
    const a = {}
    function deepCopy(newObj, oldObj){
      for(let key in oldObj){
        // 处理数组问题
        if(oldObj[key] instanceof Array){
          newObj[key] = []
          deepCopy(newObj[key], oldObj[key])
        }else{
          newObj[key] = oldObj[key]
        }
        // console.log(key); //属性名 name age
        // console.log(oldObj[key]); //属性值 张三 18
      }
    }
    deepCopy(a, obj)
    a.habby.push('跑步')
    console.log(a);
    console.log(obj);
  </script>
</body>

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

使用npm安装:

javascript 复制代码
<body>
  // 引入lodash库
  <script src="./node_modules/lodash/lodash.min.js"></script>
  <script>
    const obj = {
      name:'张三',
      age:18,
      habby:['篮球','足球'],
      family:{
        name:'李四'
      }
    }
    const a = _.cloneDeep(obj)
    a.family.name = '王五'
    console.log(a);
    console.log(obj);
  </script>
</body>

通过JSON.stringify()实现深拷贝:

javascript 复制代码
<body>
  <script>
    const obj = {
      name:'张三',
      age:18,
      habby:['篮球','足球'],
      family:{
        name:'李四'
      }
    }
    // 把对象转换成JSON字符串,再转换成对象
    const a = JSON.parse(JSON.stringify(obj))
    a.family.name = '王五'
    console.log(a);
    console.log(obj);
  </script>
</body>

三.递归函数

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

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

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

javascript 复制代码
<body>
  <script>
    let i = 1
    function fn(){
      console.log(`这是第${i}次`);
      if(i >= 6){
        return
      }
      i++
      fn()
    }
    fn()
  </script>
</body>

案例:利用递归函数实现setTimeout模拟setinterval效果,页面每隔一秒输出当前的时间

javascript 复制代码
<body>
  <div></div>
  <script>
    function getTime(){
      document.querySelector('div').innerHTML = new Date().toLocaleString()
      setTimeout(getTime, 1000)
    }
    getTime()
  </script>
</body>
相关推荐
excel1 小时前
双 Token 与前端使用 Crypto 公私钥鉴权换 Token,哪种方案更好?
前端·后端
外收内放1 小时前
Python基础语法练习题(73)
java·前端·python
风骏时光牛马2 小时前
面向复杂场景的大模型应用落地与能力优化实践
前端
小小善后师2 小时前
我做了个病历归档小程序,被 AI 识别的"最后一公里"狠狠上了一课
前端
小嘉丶学长2 小时前
Day14 · 字典与集合
java·开发语言·网络·python·学习·1024程序员节
H_Lisa2 小时前
我用 Express 写了个 MCP,Claude 直接调用我的 API 了
前端
IT_陈寒2 小时前
React的useEffect依赖数组把我坑惨了
前端·人工智能·后端
迪菲赫尔曼2 小时前
【基础篇 11】把官方源码放到服务器:版本、解压层级和安装位置,一次弄清楚
运维·服务器·开发语言·人工智能·python·yolo·目标检测
chari克里3 小时前
QT5.15.2 + msvc2022部署全流程说明(windows可联网环境)
开发语言·c++·qt