9.处理this和防抖、节流
9.1 this指向-普通函数
普通函数的调用方式决定了this的值,即【谁调用this的值 指向谁】
普通函数没有明确调用者时this值为window,严格模式下没有调用者时this的值为undefined
9.2 this指向-箭头函数
箭头函数中的this与普通函数完全不同,也不受调用方式的影响,事实上箭头函数中并不存在this !
1.箭头函数会默认帮我们绑定外层this的值,所以在箭头函数中this的值和外层的this是一样的
2.箭头函数中的this引用的就是最近作用域中的this
3.向外层作用域中,一层一层查找this,直到有this的定义
注意情况1:
在开发中【使用箭头函数前需要考虑函数中this的值】,事件回调函数使用箭头函数时,this 为全局的window
因此DOM事件回调函数如果里面需要DOM对象的this,则不推荐使用箭头函数
注意情况2:
同样由于箭头函数this的原因,基于原型的面向对象也不推荐采用箭头函数
箭头函数总结:
1.函数内不存在this,沿用上一级的
2.不适用于 构造函数,原型函数,dom事件函数等等
3.适用于 需要使用上层this的地方
9.3改变this指向
JavaScript中还允许指定函数中this的指向,有3个方法可以动态指定普通函数中this的指向
1.call()-了解
使用call方法调用函数,同时指定被调用函数中this的值
●语法:
➢thisArg: 在fun函数运行时指定的this值
➢arg1, arg2:传递的其他参数
➢返回值就是函数的返回值,因为它就是调用函数
【示例】
<body><script>const obj = {name: 'Kai'}function fn() {console.log(this) // obj}// 调用函数,改变this指向fn.call(obj)</script>
</body>
2.apply()-理解
使用apply方法调用函数,同时指定被调用函数中this的值
●语法:
➢thisArg: 在fun函数运行时指定的this值
➢argsArray: 传递的值,必须包含在数组里面
➢返回值就是函数的返回值,因为它就是调用函数
➢因此apply主要跟数组有关系,比如使用Math.max() 求数组的最大值
【示例】
<body><script>const obj = {age: 18}function fn(x, y) {console.log(this) // {age: 18}console.log(x + y) // 3}fn.apply(obj, [1, 2])</script>
</body>
3.bind()-重点
●bind() 方法不会调用函数。但是能改变函数内部this指向
●语法:
➢thisArg: 在fun函数运行时指定的this值
➢arg1, arg2:传递的其他参数
➢返回由指定的this值和初始化参数改造的 原函数拷贝(新函数)
➢因此当我们只是想改变this指向,并且不想调用这个函数的时候,可以使用bind,比如改变定时器内部的this指向
【示例】
<body><button>发送短信</button><script>// 有一个按钮,点击后禁用,1s后开启const btn = document.querySelector('button')btn.addEventListener('click', function () {this.disabled = truewindow.setTimeout(function () {// 在这个普通函数里,要将this由原来的window 改为 btnthis.disabled = false}.bind(this), 1000)})</script>
</body>
4.call apply bind 总结
9.4防抖(debounce)
●防抖:单位时间内,频繁触发事件,只执行最后一次
●使用场景:
➢搜索框搜索输入。只需用户最后一次输入完,再发送请求
➢手机号、邮箱验证输入检测
利用防抖来处理-鼠标滑过盒子显示文字
要求:鼠标在盒子上移动,鼠标停止500ms之后,里面的数字才会变化+1
实现方式:
1.lodash提供的防抖来处理
【示例】
<body><div class="box"></div><script src="lodash.min.js"></script><script>const box = document.querySelector('.box')let i = 1function move() {box.innerHTML = i++}// 利用lodash库实现防抖 - 500毫秒后执行+1// 语法:_.debounce(fun, 时间)box.addEventListener('mousemove', _.debounce(move, 500))</script>
</body>
2.手写一个防抖函数来处理
【示例】
<body><div class="box"></div><script>const box = document.querySelector('.box')let i = 1function move() {box.innerHTML = i++}// 手写防抖函数// 利用setTimeout实现// 1.声明定时器变量// 2.每次鼠标移动(事件触发)的时候都要先判断是否有定时器,有就先清除// 3.没有则开启定时器// 4.定时器里面写函数调用function debounce(fn, t) {let timer// return 返回一个匿名函数return function () {// 2.3.4if (timer) clearTimeout(timer)timer = setTimeout(function () {fn()}, t)}}box.addEventListener('mousemove', debounce(move, 500))</script>
</body>
9.5节流-throttle
●节流:单位时间内,频繁触发事件,只执行一次
●使用场景:
➢高频事件:鼠标移动mousemove、页面尺寸缩放resize、 滚动条滚动scroll等等
1.lodash提供的节流来处理
【示例】
<body><div class="box"></div><script src="lodash.min.js"></script><script>const box = document.querySelector('.box')let i = 1function move() {box.innerHTML = i++}// 利用lodash库实现节流 - 500毫秒后执行 + 1// 语法:_.throttle(fun, 时间)box.addEventListener('mousemove', _.throttle(move, 500))</script>
</body>
2.手写一个节流函数来处理
【示例】
<body><div class="box"></div><script src="lodash.min.js"></script><script>const box = document.querySelector('.box')let i = 1function move() {box.innerHTML = i++}// 手写节流函数 利用setTimeout实现// 1.声明定时器变量// 2.每次鼠标移动(事件触发)的时候都要先判断是否有定时器,有就不开启新的定时器// 3.没有则开启定时器// 4.定时器里面写函数调用,定时器里面要把定时器清空function throttle(fn, t) {let timer = nullreturn function () {if (!timer) {timer = setTimeout(function () {fn()// 清空定时器// 在 setTimeout 中是无法删除定时器的,因为定时器还在运作// 所以使用timer = null 而不是clearTimeout(timer)timer = null}, t)}}}box.addEventListener('mousemove', throttle(move, 500))</script>
</body>
3.防抖和节流总结
9.6案例-页面打开,可以记录上一次的视频播放位置
两个事件:
1.ontimeupdate事件在视频/音频(audio/video) 当前的播放位置发送改变时触发
2.onloadeddata事件在当前帧的数据加载完成且还没有足够的数据播放视频/音频(audio/video)的下一帧时触发
【部分代码示例】
<script>// 1.获取视频元素const video = document.querySelector('video')video.ontimeupdate = _.throttle(function () {// console.log(video.currentTime) 获得当前的视频时间// 把当前的时间存储到本地存储localStorage.setItem('now', video.currentTime)}, 1000)// 2.打开页面触发事件,就从本地存储里取出记录的时间,赋值给video.currentTimevideo.onloadeddata = () => {video.currentTime = localStorage.getItem('now') || 0}</script>
相关文章:

9.处理this和防抖、节流
9.1 this指向-普通函数 普通函数的调用方式决定了this的值,即【谁调用this的值 指向谁】 普通函数没有明确调用者时this值为window,严格模式下没有调用者时this的值为undefined 9.2 this指向-箭头函数 箭头函数中的this与普通函数完全不同࿰…...
Spark操作Hive表幂等性探索
前言 旁边的实习生一边敲着键盘一边很不开心的说:做数据开发真麻烦,数据bug排查太繁琐了,我今天数据跑的有问题,等我处理完问题重新跑了代码,发现报表的数据很多重复,准备全部删了重新跑。 我:你的数据操作具备幂等性吗? 实习生:啥是幂等性?数仓中的表还要考虑幂等…...

【可变形卷积3】 DCNv2 安装
使用RTM3D 代码,CenterTrack代码需要用DCN 1、安装DCNv2 (1)github上最新版的DCNv2源码在"https://github.com/CharlesShang/DCNv2",但是该版本源码不支持PyTorch1.7,如果使其支持PyTorch1.7需要做以下修改…...

归并排序 与 计数排序
目录 1.归并排序 1.1 递归实现归并排序: 1.2 非递归实现归并排序 1.3 归并排序的特性总结: 1.4 外部排序 2.计数排序 2.1 操作步骤: 2.2 计数排序的特性总结: 3. 7种常见比较排序比较 1.归并排序 基本思想: 归并排序(MERGE-SORT)是建立在归并操作上的一种…...
机器学习之逻辑回归
import numpy as np import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression # 获得数据 names[Sample code number,Clump Thickness,Uniformity…...

操作符详解上(非常详细)
目录 二进制介绍二进制2进制转10进制10进制转2进制数字2进制转8进制和16进制2进制转8进制2进制转16进制 原码、反码、补码移位操作符左移操作符右移操作符 位操作符:&、|、^逗号表达式 二进制介绍 在初学计算机时我们常常会听到2进制、8进制、10进制、16进制……...

React 高阶组件(HOC)
React 高阶组件(HOC) 高阶组件不是 React API 的一部分,而是一种用来复用组件逻辑而衍生出来的一种技术。 什么是高阶组件 高阶组件就是一个函数,且该函数接受一个组件作为参数,并返回一个新的组件。基本上,这是从 React 的组成…...

【NepCTF2023】复现
文章目录 【NepCTF2023】复现MISC与AI共舞的哈夫曼codesc语言获取环境变量 小叮弹钢琴陌生的语言你也喜欢三月七么Ez_BASIC_IImisc参考 WEBez_java_checkinPost Crad For You独步天下配置环境独步天下-镜花水月环境变量提权 独步天下-破除虚妄总结 独步天下-破除试炼_加冕成王知…...
大文件切片上传
创建组件:创建一个组件用于处理文件上传,命名为Upload.vue。 <template><div><input type"file" change"handleFileChange" /><button click"startUpload">开始上传</button></div> …...

ubuntu切换python版本
在没有安装类似anoconda的管理工具的时候,我们常常会被Ubuntu下的Python版本切换问题所头疼。 可以使用update-alternatives工具进行python版本的任意切换 当使用update-alternatives工具来切换Ubuntu系统上的Python版本时,您实际上是在系统范围内选择…...
docker 安装 elasticsearch、kibana 7.4.2
切换root 用户 su root 拉起镜像 docker pull elasticsearch:7.4.2 docker pull kibana:7.4.2 #1、创建Elasticsearch配置文件夹 mkdir -p /mydata/elasticsearch/config #2、创建Elasticsearch数据文件夹 mkdir -p /mydata/elasticsearch/data #3、创建Elasticsearch插件…...
【es6】函数参数设置默认值
1、es6之前的函数参数默认值写法 1.1、使用短路或||的写法 当y为空时,y判断为false ,走||右边的,所以y world;当y不为空时,y判断为true,不需要再运行||右边的,所以 y y function log(x, y) {y y || W…...

Pytest和Unittest测试框架的区别?
如何区分这两者,很简单unittest作为官方的测试框架,在测试方面更加基础,并且可以再次基础上进行二次开发,同时在用法上格式会更加复杂;而pytest框架作为第三方框架,方便的地方就在于使用更加灵活࿰…...
C#基础知识(一)
一、C#程序结构 《1》命名空间的声明(namespace declaration) 《2》一个class 《3》class方法 《4》class属性 《5》一个main方法 《6》语句(statements)&表达式(Expressions) 《7》注释 注:…...

我还不知道?Android组件化插件化模块化
Android组件化、插件化和模块化是针对Android应用程序开发的一种架构设计思想和开发方式。 组件化(Componentization): 组件化是将一个大型的Android应用程序拆分成多个独立的组件(Module),每个组件可以独…...

借助 AI 工具,真的能成为 10x 工程师?
或许你听说过 10x 工程师吗? 如果你问猎头公司 10x 工程师是什么意思,他们可能会说 “生产力”!10x 是指完成任务比别人快 10 倍的工程师。 2019 年,Twitter 上就曾经对 10 x 工程师这一议题有过一次空前热烈的讨论,引…...
TypeScript 面向对象
TypeScript 接口 TypeScript 接口定义如下: interface interface_name { } 以下实例中,我们定义了一个接口 IPerson,接着定义了一个变量 customer,它的类型是 IPerson。 customer 实现了接口 IPerson 的属性和方法。 interf…...
k8s 中快速启动curl pod 做api test
场景 k8s上运行的pod需要进行api测试,由于开发使用的镜像都是最小化构建,不能保证现有的pod中一定有curl工具,于是需要启动一个带有curl工具的测试pod专门进行api测试 指令 kubectl run curl-test-pod --imagecurlimages/curl -n {namespace} -i --tty -- sh上述指令实现在指…...
神经网络基础-神经网络补充概念-56-迁移学习
迁移学习(Transfer Learning)是一种机器学习技术,旨在将在一个任务上学到的知识或模型迁移到另一个相关任务上,以提高新任务的性能。迁移学习的核心思想是通过利用源领域(source domain)的知识来改善目标领…...
力扣:65. 有效数字(Python3)
题目: 有效数字(按顺序)可以分成以下几个部分: 一个 小数 或者 整数(可选)一个 e 或 E ,后面跟着一个 整数 小数(按顺序)可以分成以下几个部分: (…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...

Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...

【Veristand】Veristand环境安装教程-Linux RT / Windows
首先声明,此教程是针对Simulink编译模型并导入Veristand中编写的,同时需要注意的是老用户编译可能用的是Veristand Model Framework,那个是历史版本,且NI不会再维护,新版本编译支持为VeriStand Model Generation Suppo…...
小木的算法日记-多叉树的递归/层序遍历
🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...