JavaScript进阶(day04:高阶技巧)

2023-12-24 07:14:30

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes

觉得有帮助的同学,可以点心心支持一下哈

一、深浅拷贝

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

1.浅拷贝

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

拷贝对象:

①Object.assgin(新对象,拷贝对象)

②const 新对象={...拷贝对象}

拷贝数组:

①Array.prototype.concat(新数组,拷贝数组)

②const 新数组={...拷贝数组}

总结(直接赋值和浅拷贝)

2.深拷贝

拷贝的是对象,不是地址

2.1通过递归实现深拷贝

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

案例(利用递归函数实现setTimeout模拟setInterval效果)

      const div = document.querySelector('div')
      function time() {
        div.innerHTML = Date().toLocaleString()
        setTimeout(time, 1000)
      }
      time()

深拷贝实现(递归)

// 定义两个对象
let a = {
  name: '小明',
  age: 18,
  hobby: ['唱歌', '玩游戏'],
  brother: {
    name: '小黑',
    age: 19
  }
}
let b = {}
// 定义深拷贝函数
function deepCopy(newObject, oldObject) {
  // 1.遍历旧对象
  // key是对象里面的属性名
  for (let key in oldObject) {
    // 如果对象里面包含数组,则对数组进行循环(递归)
    if (oldObject[key] instanceof Array) {
      newObject[key] = []
      deepCopy(newObject[key], oldObject[key])
    } // 如果对象里面包含对象,则对对象进行循环(递归)
    else if (oldObject[key] instanceof Object) {
      newObject[key] = {}
      deepCopy(newObject[key], oldObject[key])
    } else {
      newObject[key] = oldObject[key]
    }
  }
}
deepCopy(b, a)

2.2lodash/cloneDeep

2.3通过JSON.stringify()实现

总结

二、异常处理

了解JavaScript中程序异常处理的方法,提升代码运行的健壮性

throw抛异常

语法:throw new Error("提示信息")

总结:

①throw抛出异常信息,程序也会终止执行

②throw后面跟的是错误提示信息

③Error对象配合throw使用,能够设置更详细的错误信息

总结

try/catch捕获异常

总结:

①try...catch用于捕获错误信息

②将预估可能发生错误的代码写在try代码段中

③如果try代码段中出现错误后,会执行catch代码段,并截获到错误信息

④finally不管是否有错误,都会执行

总结

debugger

三、处理this

this指向

this指向-普通函数

总结

this指向-箭头函数

注意情况1

注意情况2

总结

改变this

call()(了解)

apply()

call和apply的区别

bind()

总结(call、apply、bind)

四、性能优化

4.1防抖

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

实现方式:

  • lodash提供的防抖来处理
  • 手写一个防抖函数来处理

案例(利用防抖来处理-鼠标滑过盒子显示文字(lodash))

 <script src="./js/lodash.min.js"></script>
    <script>
      // 鼠标在盒子上移动,里面的数字就会变化加1
      // 1.获取元素
      const div = document.querySelector('div')
      const h2 = document.querySelector('h2')
      // 2.绑定鼠标移动事件
      let i = 1
      div.addEventListener(
        'mousemove',
        _.debounce(function () {
          h2.innerHTML = i++
        }, 500)
      )
    </script>

案例(利用防抖来处理-鼠标滑过盒子显示文字(手写防抖函数))

    <script src="./js/lodash.min.js"></script>
    <script>
      // 鼠标在盒子上移动,里面的数字就会变化加1
      // 1.获取元素
      const div = document.querySelector('div')
      const h2 = document.querySelector('h2')
      // 2.定义鼠标移动函数
      let i = 1
      function mousemove() {
        h2.innerHTML = i++
      }
      // 手写防抖函数,核心是利用setTimeout定时器来实现
      // 1.声明一个定时器变量
      // 2.每次鼠标移动(事件触发)的时候都要先判断是否有定时器,如果有的话先清除之前的定时器
      // 3.如果没有定时器,则开启定时器,存入到定时器变量里面
      // 4.定时器里面写函数调用
      div.addEventListener('mousemove', debounce(mousemove, 500))
      function debounce(fn, t) {
        let timeId
        // return 返回一个匿名函数
        return function () {
          //2.3.4
          if (timeId) clearTimeout(timeId)
          timeId = setTimeout(function () {
            fn()
          }, t)
        }
      }

总结

4.2节流 - throttle

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

实现方式:

  • lodash提供的节流函数来处理
  • 手写一个防抖函数来处理

案例(利用节流来处理-鼠标滑过盒子显示文字(lodash))

 <script src="./js/lodash.min.js"></script>
    <script>
      // 鼠标在盒子上移动,里面的数字就会变化加1
      // 1.获取元素
      const div = document.querySelector('div')
      const h2 = document.querySelector('h2')
      // 2.绑定鼠标移动事件
      let i = 1
      div.addEventListener(
        'mousemove',
        _.throttle(function () {
          h2.innerHTML = i++
        }, 3000)
      )
    </script>

案例(利用节流来处理-鼠标滑过盒子显示文字(手写节流函数))

 <script src="./js/lodash.min.js"></script>
    <script>
      // 鼠标在盒子上移动,里面的数字就会变化加1
      // 1.获取元素
      const div = document.querySelector('div')
      const h2 = document.querySelector('h2')
      let i = 1
      function mouseMove() {
        h2.innerHTML = i++
      }
      div.addEventListener('mousemove', throttle(mouseMove, 500))
      // 核心思路
      // 1.声明一个定时器变量
      // 2.当鼠标滑过都先判断有没有定时器,如果有定时器则不开启新的定时器
      // 3.如果没有定时器则开启定时器,并存在定时器变量里面
      // 4.定时器里面要调用执行的函数,定时器里面要把定时器清空
      // 绑定鼠标移动事件
      function throttle(fn, time) {
        let timeId = null
        return function () {
          if (!timeId) {
            timeId = setTimeout(function () {
              fn()
              timeId = null
            }, time)
          }
        }
      }
    </script>

总结

总结(防抖和节流)

五、综合案例(页面打开,可以记录上一次的视频播放位置)

 // 获取元素
      const video = document.querySelector('video')
      // let time = 0
      // 给video绑定timeupdate事件,该事件会在视频/音频当前位置发生改变时触发
      // 因为事件执行频率太快,需要进行节流
      video.addEventListener(
        'timeupdate',
        _.throttle(function () {
          // 把当前视频播放的位置存储到浏览器中
          localStorage.setItem('videoTime', video.currentTime)
        }, 1000)
      )
      // 给video绑定loadeddata事件,该事件会在页面加载时触发
      video.addEventListener('loadeddata', function () {
        // 将本地存储的时间赋值给视频现在播放的时间,实现视频从上一次的视频播放位置开始播放
        video.currentTime = localStorage.getItem('videoTime') || 0
      })

文章来源:https://blog.csdn.net/weixin_51591826/article/details/135163496
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。