JavaScript进阶day4

news2024/11/13 0:14:26

目录

1.深浅拷贝

1.1 浅拷贝

1.1.1 浅拷贝的认识

1.1.2 浅拷贝的小结

1.2 深拷贝

1.2.1 递归实现深拷贝

1.2.2 js类库lodash/cloneDeep实现深拷贝

1.2.3 JSON.stringify()实现深拷贝

2.异常处理

2.1 throw 抛异常

2.2 try /catch 捕获异常

2.3 debugger

3.处理this

3.1 this指向

3.1.1 普通函数

3.1.2 箭头函数

3.2 改变this

3.2.1 call()

3.2.2 apply()

3.2.3 bind()--重点

4.性能优化

4.1 防抖

4.2 节流

4.3 总结

5.节流的综合案例


1.深浅拷贝

开发中我们经常需要复制一个对象。如果直接用赋值会有下面问题:

因为对象赋值是地址,因此修改其中一个,另外一个也会受到影响。

1.1 浅拷贝

1.1.1 浅拷贝的认识

浅拷贝:拷贝的是地址
常见方法:
  • 1. 拷贝对象:Object.assgin() / 展开运算符 {...obj} 拷贝对象
  • 2.拷贝数组:Array.prototype.concat() 或者 [...arr]

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

1.1.2 浅拷贝的小结

1. 直接赋值和浅拷贝有什么区别?
  • 直接赋值的方法,只要是对象,都会相互影响,因为是直接拷贝对象栈里面的地址
  • 浅拷贝如果是一层对象,不相互影响,如果出现多层对象拷贝还会相互影响
2. 浅拷贝怎么理解?
  • 拷贝对象之后,里面的属性值是简单数据类型直接拷贝值
  • 如果属性值是引用数据类型则拷贝的是地址

1.2 深拷贝

深拷贝:拷贝的是对象,不是地址

常见方法:
  • 1. 通过递归实现深拷贝
  • 2. lodash/cloneDeep
  • 3. 通过JSON.stringify()实现

1.2.1 递归实现深拷贝

函数递归:
  • 如果一个函数在内部可以调用其本身,那么这个函数就是递归函数
  • 简单理解:函数内部自己调用自己, 这个函数就是递归函数
  • 递归函数的作用和循环效果类似
  • 由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件 return

练习:

利用递归函数实现 setTimeout 模拟 setInterval效果

需求:
①:页面每隔一秒输出当前的时间
②:输出当前时间可以使用:new Date().toLocaleString()
代码:
递归实现深拷贝:
实现步骤:
  • 通过递归函数来实现
  • 如果是基本数据类型的键值对,就正常赋值
  • 如果是引用类型就需要递归函数,先处理数组后处理对象

1.2.2 js类库lodash/cloneDeep实现深拷贝

访问:https://www.lodashjs.com/

然后下载并引入js文件,才可以使用封装好的cloneDeep()

1.2.3 JSON.stringify()实现深拷贝

怎么做到的?

刚开始obj是一个对象,然后转换为JSON字符串,后面有parse重新转为对象,又因为前面的对象和后面的对象的地址不一样,因此可以实现深拷贝。

2.异常处理

2.1 throw 抛异常

异常处理是指预估代码执行过程中可能发生的错误,然后最大程度的避免错误的发生导致整个程序无法继续运行。

总结:
  • 1. throw 抛出异常信息,程序也会终止执行
  • 2. throw 后面跟的是错误提示信息
  • 3. Error 对象配合 throw 使用,能够设置更详细的错误信息(会指出第几行代码出错)

2.2 try /catch 捕获异常

我们可以通过try / catch 捕获错误信息(浏览器提供的错误信息) ,try 试试 catch 拦住 finally 最后。

总结:
  • 1. try...catch 用于捕获错误信息
  • 2. 将预估可能发生错误的代码写在 try 代码段中
  • 3. 如果 try 代码段中出现错误后,会执行 catch 代码段,并截获到错误信息
  • 4. finally 不管是否有错误,都会执行
  • 5. catch捕获到错误信息,程序不会停止

2.3 debugger

当代码多的时候,不方便找到对应的片段,就可以加debugger,浏览器控制台就会定位到

该debugger,省去了找代码的时间。

3.处理this

3.1 this指向

学习路径:
  • 1. 普通函数this指向
  • 2. 箭头函数this指向

3.1.1 普通函数

普通函数的调用方式决定了 this 的值,即【谁调用 this 的值指向谁】
普通函数没有明确调用者时 this 值为 window,严格模式下没有调用者时 this 的值为 undefined

3.1.2 箭头函数

箭头函数中的 this 与普通函数完全不同,也不受调用方式的影响,事实上 箭头函数中并不存在 this 
  • 1. 箭头函数会默认帮我们绑定外层 this 的值,所以在箭头函数中 this 的值和外层的 this 是一样的
  • 2.箭头函数中的this引用的就是最近作用域中的this
  • 3.向外层作用域中,一层一层查找this,直到有this的定义

注意情况1:
在开发中【使用箭头函数前需要考虑函数中 this 的值】,事件回调函数使用箭头函数时,this 为全局的 window ,因此DOM事件回调函数 如果里面需要 DOM对象的this,则不推荐使用箭头函数

注意情况2:
同样由于箭头函数 this 的原因,基于原型的面向对象也不推荐采用箭头函数

总结:

1.函数内不存在this,沿用上一级的,过程:向外层作用域中,一层
一层查找this,直到有this的定义
2.不适用
  •  构造函数
  • 原型函数
  • dom事件函数
3. 适用 :需要使用上层this的地方

3.2 改变this

3.2.1 call()

作用:使用 call 方法调用函数,同时传入需要被指定的this对象,来实现改变函数的this对象

语法:

参数说明:

  • thisArg:在 fun 函数运行时指定的 this 值
  • arg1,arg2:传递的其他参数
  • 返回值就是函数的返回值,因为它就是调用函数

3.2.2 apply()

作用:使用 apply 方法调用函数,同时指定被调用函数中 this 的值

语法:

参数说明:

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

3.2.3 bind()--重点

作用:bind() 方法不会调用函数。但是能改变函数内部this 指向

语法:

参数说明:

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

4.性能优化

4.1 防抖

防抖(debounce),所谓防抖,就是单位时间内,频繁触发事件,只执行最后一次。
举个例子:王者荣耀回城,只要被打断回城,就需要重新来按回城。
开发使用场景- 搜索框防抖
搜索框搜索输入,需要用户最后一次输入完,再发送请求。
案例:
利用防抖来处理-鼠标滑过盒子显示文字
实现方式:
  • 1.lodash提供的防抖函数来处理
  • 2.手写一个防抖函数来处理

需求: 鼠标在盒子上移动,鼠标停止之后,500ms后里面的数字就会变化+1
核心思路:  

①: 写一个demo函数 ,来控制这个操作函数(mouseMove), 500ms之后才去执行这个函数

②: 节流函数传递2个参数, 第一个参数 mouseMove函数,第二个参数 指定时间500ms

③: 鼠标移动事件,里面写的是demo函数

④:定时器有就先清除,后再添加新的定时器

代码:
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
  <style>
    .box {
      width: 500px;
      height: 500px;
      background-color: #ccc;
      color: #fff;
      text-align: center;
      font-size: 100px;
    }
  </style>
</head>

<body>
  <div class="box"></div>
  <script>
   
     /* 手写防抖函数 */

    // 获取对象
    const box = document.querySelector('.box')

    let i = 1
    // 写入html文档
    function mouseMove() {
      box.innerHTML = i++
    }

    // 鼠标移动事件,因为 demo(mouseMove, 500)返回的是一个回调函数,因此没问题
    box.addEventListener('mousemove', demo(mouseMove, 500))

    //     核心思路:
    // ①: 写一个demo函数 ,来控制这个操作函数(mouseMove), 500ms之后才去执行这个函数
    // ②: 节流函数传递2个参数, 第一个参数 mouseMove函数,第二个参数 指定时间500ms
    // ③: 鼠标移动事件,里面写的是demo函数
    function demo(fun, time) {
      let timeOut
      return function () {
        // 定时器有就先删除,后再添加新的定时器
        if (timeOut) {
          clearTimeout(timeOut)
        }
        timeOut = setTimeout(fun, time)
      }
    }

  </script>
</body>

</html>

4.2 节流

节流(throttle),所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。
举个例子:王者荣耀技能冷却,期间无法继续使用技能。
开发使用场景 – 小米 轮播图点击效果 、 鼠标移动、页面尺寸缩放resize就可以加节流。
假如一张轮播图完成切换需要300ms, 不加节流效果,快速点击,则嗖嗖嗖的切换。
加上节流效果, 不管快速点击多少次, 300ms时间内,只能切换一张图片。
高级软件人才培训专家

 

案例:
利用防抖来处理-鼠标滑过盒子显示文字
实现方式:
  • 1.lodash提供的节流函数来处理
  • 2.手写一个节流函数来处理

需求: 鼠标在盒子上移动,鼠标停止之后,500ms后里面的数字就会变化+1
核心思路:  

①: 写一个throttle函数 ,来控制这个操作函数(mouseMove), 500ms之后才去执行这个函数

②: 节流函数传递2个参数, 第一个参数 mouseMove函数,第二个参数 指定时间500ms

③: 鼠标移动事件,里面写的是throttle函数

④:如果没有定时器就开启,如果有定时器则不开启新的定时器

        //   1.1 定时器里面调用函数

        //   1.2 定时器里面清除该定时器

代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
  <style>
    .box {
      width: 500px;
      height: 500px;
      background-color: #ccc;
      color: #fff;
      text-align: center;
      font-size: 100px;
    }
  </style>
</head>

<body>
  <div class="box"></div>
  <script>

    /* 手写节流函数 */

    // 获取对象
    const box = document.querySelector('.box')

    let i = 1
    // 写入html文档
    function mouseMove() {
      box.innerHTML = i++
    }

    // 鼠标移动事件
    box.addEventListener('mousemove', throttle(mouseMove, 500))

    //     核心思路:
    // ①: 写一个throttle函数 ,来控制这个操作函数(mouseMove), 500ms之后才去执行这个函数
    // ②: 节流函数传递2个参数, 第一个参数 mouseMove函数,第二个参数 指定时间500ms
    // ③: 鼠标移动事件,里面写的是throttle函数
    function throttle(fun, time) {
      let timeOut = null
      return function () {
        // 1.如果没有定时器就开启,如果有定时器则不开启新的定时器
        //   1.1 定时器里面调用函数
        //   1.2 清除定时器
        if (!timeOut) {
          timeOut = setTimeout(function () {
            // 调用要执行的函数
            fun()
            // 开启定时器里面清理定时器
            // 设置null的原因是因为开启定时器里面直接clearTimeout会出现异常情况,因此直接把变量赋值为null
            // 异常情况就是开启定时器是timeOut = 1,在里面调用了clearTimeout的timeOut还是为1
            timeOut = null
          }, time)
        }

      }
    }

  </script>
</body>

</html>

注意:setTimeout中无法删除定时器,因为定时器还在运作,因此用timeOut = null,而不是

clearTimeout(timeOut)

4.3 总结

Lodash 库 实现节流和防抖

1. 节流和防抖的区别是?
  • 节流: 就是指连续触发事件但是在 n 秒中只执行一次函数,比如 可以利用节流实现 1s之内 只能触发一次鼠标移动事件
  • 防抖:如果在 n 秒内又触发了事件,则会重新计算函数执行时间
2. 节流和防抖的使用场景是?
  • 节流: 鼠标移动,页面尺寸发生变化,滚动条滚动等开销比较 大的情况下
  • 防抖: 搜索框输入,设定每次输入完毕n秒后发送请求,如果期 间还有输入,则从新计算时间

5.节流的综合案例

页面打开,可以记录上一次的视频播放位置

先认识两个事件:
  • ①:ontimeupdate 事件在视频/音频(audio/video)当前的播放位置发送改变时触发
  • ②:onloadeddata 事件,每次打开页面,加载当前帧的数据
  • ③:利用本地存储视频播放时间,下次打开页面就可以重本地存储获取该时间来实现

思路:
  • 1. 在ontimeupdate事件触发的时候,每隔1秒钟,就记录当前时间到本地存储
  • 2. 下次打开页面, onloadeddata 事件触发,就可以从本地存储取出时间,让视频从取出的时间播放,如果没有就默认为0s
  • 3. 获得当前时间 video.currentTime
效果图:
代码:
<body>
  <div class="container">
    <div class="header">
      <a href="http://pip.itcast.cn">
        <img src="https://pip.itcast.cn/img/logo_v3.29b9ba72.png" alt="" />
      </a>
    </div>
    <div class="video">
      <video src="https://v.itheima.net/LapADhV6.mp4" controls></video>
    </div>
    <div class="elevator">
      <a href="javascript:;" data-ref="video">视频介绍</a>
      <a href="javascript:;" data-ref="intro">课程简介</a>
      <a href="javascript:;" data-ref="outline">评论列表</a>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
  <script>
    // 获取对象
    const video = document.querySelector('video')
    // 播放视频就会触发(利用节流让它一秒只触发一次)
    video.ontimeupdate = _.throttle(function () {
      // console.log(11)
      localStorage.setItem('currentTime', video.currentTime)
    }, 1000)

    // 下次打开页面,视频的进度停留在 video.currentTime
    video.onloadeddata = function () {
      video.currentTime = localStorage.getItem('currentTime') || 0
    }
  </script>
</body>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2129619.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

嵌入式边缘计算:融合创新与未来展望

本文深入探讨了嵌入式边缘计算。首先解析了其概念&#xff0c;指出它是将计算和数据存储能力嵌入边缘设备以实现本地数据处理。阐述了其低延迟、高可靠性、节省带宽、隐私保护和高效节能等技术特点。接着介绍了关键技术&#xff0c;包括嵌入式系统设计、边缘计算架构、通信技术…

关于QT服务端客户端的聊天

服务段头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include<QTcpServer> #include<QMessageBox> #include<QDebug> #include<QList> #include<QTcpSocket>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_N…

设计一个算法,找出由str1和str2所指向两个链表共同后缀的起始位置

假定采用带头结点的单链表保存单词&#xff0c;当两个单词有相同的后缀时&#xff0c;则可共享相同的后缀存储空间&#xff0c;例如&#xff0c;’loading’和’being’的存储映像如下图所示。 设str1和str2分别指向两个单词所在单链表的头结点&#xff0c;链表结点结构为 data…

HashTable哈希表

概念 散列表(Hash Table)&#xff0c;又称哈希表。是一种数据结构&#xff0c;特点是:数据元素的关键字与其存储地址直接相关 在顺序结构以及树型结构中&#xff0c;数据元素的关键字与其存储位置没有对应的关系&#xff0c;因此在查找一个元素时&#xff0c;必须要经过关键码…

KV260 进阶开发(PYNQ驱动开发+Pixel Pack)

目录 1. 简介 2. PixelPacker HLS 实现 2.1 PixelPacker HLS 源码 2.2 PixelPacker 功能简介 2.3 头文件介绍 2.4 启动间隔 II 2.5 Case V24 片段解释 3. PixelPacker Py 驱动 3.1 PixelPacker Py 源码 3.2 PixelPacker 类详解 3.3 property 装饰器 3.4 操作寄存器…

一、(JS)JS中鼠标事件-mouseenter、mouseleave和mouseover、mouseout区别

一、单个元素下mouseenter、mouseleave和mouseover、mouseout没有区别 我们先来一个demo&#xff0c;设置一个div <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"…

INIC6081量产工具下载,initio6081开卡软件分享

国内固态硬盘常用&#xff0c;且有量产工具流传出来的主控厂商包括慧荣、群联、点序、英韧、得一微、瑞昱、联芸、迈威、国科、华澜微等等。 每个主控需要用各自对应的量产工具&#xff0c;不同的量产工具支持的闪存颗粒也有差异&#xff0c;因此要根据固态硬盘实际的主控型号…

基于SSM的酒店客房管理系统+LW示例参考

系列文章目录 1.基于SSM的洗衣房管理系统原生微信小程序LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统LW参考示例 3.基于SpringBootVue的企业人事管理系统LW参考示例 4.基于SSM的高校实验室管理系统LW参考示例 5.基于SpringBoot的二手数码回收系统原生微信小程序LW参考示…

Visual Studio 设置文件默认编码格式、行尾符等

文章目录 1.命令方式2.EditorConfig配置 1.命令方式 2.EditorConfig配置 微软官方文档 使用EditorConfig方式配置&#xff0c;无需Visual Studio软件自带对EditorConfig的支持&#xff0c;无需插件 将下面.editorconfig文件放在项目根目录下 root true # 所在目录是根目录…

基于SSM的二手交易管理系统的设计与实现 (含源码+sql+视频导入教程+文档)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的二手交易管理系统1拥有两种角色 管理员&#xff1a;商品管理、订单管理、充值管理、用户管理等用户&#xff1a;发布商品、查看闲置、充值账户、查看所有订单、发布求购信息、修…

今年白银市场的供需关系矛盾

自从2020年以来&#xff0c;白银手持连续4年都出现了供需缺口&#xff0c;预计今年的供需缺口将进一步扩大。2015年以来&#xff0c;白银总产量始终维持10亿盎司水平上下波动&#xff0c;2015~2023年的年均复合增速在0.4%&#xff0c;预计2024年的产量将下降1%。矿产银的产量从…

day-54 求出最多标记下标

思路 假设nums的长度为len&#xff0c;则返回数最大最大为&#xff08;len/2&#xff09;*2,所以可以将数组分为两部分&#xff0c;[0(len-1)/2]为一部分&#xff0c;[(len-1&#xff09;/2len-]为第二部分 解题过程 指针right从第二部分从右向左开始遍历&#xff0c;指针left…

Tensorboard 基础与使用-——界面介绍

在导入运行tensorboard得到一个event file文件。 tensorboard基本原理是这样的 python代码中将可视化的数据记录到event file中&#xff0c;保存至硬盘 采用tensorboard对event file文件进行读取&#xff0c;并在web端进行可视化 指令启动&#xff1a; tensorboard --logdir…

大数据Flink(一百一十七):Flink SQL的窗口操作

文章目录 Flink SQL的窗口操作 一、窗口的概述 二、Group Windows 1、​​​​​​​滚动窗口&#xff08;TUMBLE&#xff09; 2、​​​​​​​​​​​​​​滑动窗口&#xff08;HOP&#xff09; 3、​​​​​​​​​​​​​​Session 窗口&#xff08;SESSION&am…

军事目标无人机视角检测数据集 3500张 坦克 带标注voc

数据集概述 该数据集包含3500张无人机拍摄的图像&#xff0c;主要用于坦克目标的检测。数据集已经按照VOC&#xff08;Visual Object Classes&#xff09;标准进行了标注&#xff0c;适用于训练深度学习模型&#xff0c;特别是物体检测模型。 数据集特点 目标明确&#xff1…

通信工程学习:什么是GFP通用成帧规范

GFP&#xff1a;通用成帧规范 GFP通用成帧规范&#xff08;Generic Framing Procedure&#xff09;是一种先进的数据业务适配的通用协议和映射技术&#xff0c;由国际电联ITU-T的G.7041标准定义。该技术旨在透明地将各种不同物理层或逻辑链路层信号适配进入SDH&#xff08;同步…

C语言初识编译和链接

目录 翻译环境和运行环境编译环境预编译编译词法分析语法分析语义分析 汇编 链接运行环境 翻译环境和运行环境 在ANSI C的任何⼀种实现中&#xff0c;存在两个不同的环境。 第1种是翻译环境&#xff0c;在这个环境中源代码被转换为可执⾏的机器指令&#xff08;⼆进制指令&…

【Vue】1.v-指令、computed、watch

1 Vue 实例 注&#xff1a;此文件是 vue 根实例&#xff0c;data 可以 是一个对象 即 data:{ } 但是在其他 .vue 组件文件中&#xff0c;data 必须 是一个函数&#xff0c;返回一个新的对象&#xff0c;以避免多个组件实例之间的数据相互干扰 即 data(){ } <!DOCTYPE html&g…

前端正确设置资源上下文路径ContextPath(发布目录outDir 、公共基础路径),保证打包部署后站点能正常加载资源。

文章目录 引言I 处理资源上下文路径ContextPathjavascript对象获取上下文路径使用`./` 加载资源文件Vite 的basepublicPath是webpack部署应用包时的基本 URLII 知识扩展:URL的识别2.1 标准的链接格式2.2 URL中的?涵义2.3 URL中的&涵义2.4 传参III #fragment3.1为网页位置…

Vue2使用Vue CLI学习笔记

Vue2构建项目分析 Vue学习官网 Vue CLI官方 # 全局安装&#xff0c;只要装一次&#xff0c;以管理员身份 npm install -g vue/cli # 查看脚手架工具版本 vue --version # 创建项目&#xff0c;注意路径&#xff0c;名称不能是中文 vue create my-project # 启动项目&#xff…