手写系列之--call/apply/bind/防抖/节流

2023-11-19

call

call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数
语法:function.call(thisArg, arg1, arg2, …)

JavaScript中由于函数的this指向它的直接调用者,我们变更调用者即完成this指向的变更:

Function.prototype.myCall = function(thisArg, ...args) {
    const fn = Symbol('fn')        // 声明一个独有的Symbol属性, 防止fn覆盖已有属性
    thisArg = thisArg || window    // 若没有传入this, 默认绑定window对象
    thisArg[fn] = this              // this指向调用call的对象,即我们要改变this指向的函数
    const result = thisArg[fn](...args)  // 执行当前函数
    delete thisArg[fn]              // 删除我们声明的fn属性
    return result                  // 返回函数执行结果
}

apply

apply() 方法调用一个具有给定this值的函数,以及作为一个数组(或类似数组对象)提供的参数。
语法:func.apply(thisArg, [argsArray])

applycall类似,区别在于call接收参数列表,而apply接收一个参数数组,所以我们在call的实现上简单改一下入参形式即可

Function.prototype.myApply = function(thisArg, args) {
    const fn = Symbol('fn')        // 声明一个独有的Symbol属性, 防止fn覆盖已有属性
    thisArg = thisArg || window    // 若没有传入this, 默认绑定window对象
    thisArg[fn] = this              // this指向调用call的对象,即我们要改变this指向的函数
    const result = thisArg[fn](...args)  // 执行当前函数(此处说明一下:虽然apply()接收的是一个数组,但在调用原函数时,依然要展开参数数组。可以对照原生apply(),原函数接收到展开的参数数组)
    delete thisArg[fn]              // 删除我们声明的fn属性
    return result                  // 返回函数执行结果
}

bind

bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
语法: function.bind(thisArg, arg1, arg2, …)

注意点:

  1. bind()除了this还接收其他参数,bind()返回的函数也接收参数,这两部分的参数都要传给返回的函数
  2. new会改变this指向:如果bind绑定后的函数被new了,那么this指向会发生改变,指向当前函数的实例
  3. 保留原函数在原型链上的属性和方法
Function.prototype.myBind = function (thisArg, ...args) {
    var self = this
    // new优先级
    var fbound = function () {
        self.apply(this instanceof self ? this : thisArg, args.concat(Array.prototype.slice.call(arguments)))
    }
    // 继承原型上的属性和方法
    fbound.prototype = Object.create(self.prototype);

    return fbound;
}

例子:

function f(y, z){
    return this.x + y + z;
}
var m = f.bind({x : 1}, 2);
console.log(m(3));
//6
//这里bind方法会把它的第一个实参绑定给f函数体内的this,
//所以这里的this即指向{x : 1}对象,从第二个参数起,会依次传递给原始函数,这里的第二个参数2,即是f函数的y参数,
//最后调用m(3)的时候,这里的3便是最后一个参数z了,所以执行结果为1 + 2 + 3 = 6

防抖

防抖,即短时间内大量触发同一事件,只会执行一次函数,实现原理为设置一个定时器,约定在xx毫秒后再触发事件处理,每次触发事件都会重新设置计时器,直到xx毫秒内无第二次操作,防抖常用于搜索框/滚动条的监听事件处理,如果不做防抖,每输入一个字/滚动屏幕,都会触发事件处理,造成性能浪费。

function debounce(func, wait) {
    let timeout = null
    return function() {
        let context = this
        let args = arguments
        if (timeout) {
          clearTimeout(timeout)
          timeout = null;
        }
        timeout = setTimeout(() => {
            func.apply(context, args)
        }, wait)
    }
}

节流

防抖是延迟执行,而节流是间隔执行,函数节流即每隔一段时间就执行一次,
和防抖的区别在于,防抖每次触发事件都重置定时器,而节流在定时器到时间后再清空定时器

//实现一:设置一个定时器,约定xx毫秒后执行事件,如果时间到了,那么执行函数并重置定时器
function throttle(func, wait) {
    let timeout = null
    return function() {
        let context = this
        let args = arguments
        if (!timeout) {
            timeout = setTimeout(() => {
                timeout = null
                func.apply(context, args)
            }, wait)
        }

    }
}
//实现二:使用两个时间戳prev旧时间戳和now新时间戳,每次触发事件都判断二者的时间差,
//如果到达规定时间,执行函数并重置旧时间戳
function throttle(func, wait) {
    var prev = 0;
    return function() {
        let now = Date.now();
        let context = this;
        let args = arguments;
        if (now - prev > wait) {
            func.apply(context, args);
            prev = now;
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

手写系列之--call/apply/bind/防抖/节流 的相关文章

  • Python自定义异常 Python Custom Exception

    个人主页 Aurora 如果文章有什么需要改进的地方还请各位大佬指正 如果我的文章对你有帮助 关注 点赞 收藏 一 python自定义异常 1 自定义一个CustomException类 继承Exception类 2 编写CustomExc
  • cur.execute(sql,args)和cur.execute(sql)的区别

    python代码示例 方式一 userid 123 sql select id name from user where id s userid cur execute sql 方式二 sql语句模板中的参数填充符是 s 而不是 s 且多个
  • Linux上开发常见问题整理

    Linux上开发常见问题整理 1 java工程在linux上运行测试 首先要有一个main方法作为主类 程序的入口 右键 gt Run As gt javaapplication生成配置文件入口 右键该工程 gt Export gt Run
  • LaTeX 多行公式、公式对齐以及输入矩阵的方法

    一 LaTex显示 大括号连接的 多行公式 公式组合 使用cases环境实现公式的组合 分隔公式和条件 具体LaTex代码如下 D x begin cases lim limits x to 0 frac a x b c x lt 3 pi
  • tshark 解析pcap中带TLS协议的数据包

    tshark的简单用法参考 tshark解析本地pcap数据包提取五元组 src ip src port proto dst ip dst port 与时间戳 包长 详细用法 官方DOC 比如提取一个数据包 my pcap 中全部带有TLS
  • Oracle数据恢复:强制Resetlogs的可能数据损失

    Oracle数据恢复 强制Resetlogs的可能数据损失 Oracle数据恢复 格式化 ASM及字典损坏案例三则 ORA 00600 kcratr nab less than odr案例一则 SMON recover undo segme
  • 简易DOCKER/K8S使用心得

    1 DOCKER安装 1 1 前置环境 首先 如果使用CentOS 你至少需要7 4以上 从内核角度来说 建议使用8 2及以上 如果是7 4以下的版本 可以通过设置仓库到7 4以上版本 再 yum install centos releas
  • 计算机内存数值存储方式-原码、反码、补码、数值溢出

    计算机内存数值存储方式 1 原码 一个数的原码 原始的二进制码 有如下特点 最高位做为符号位 0表示正 为1表示负 其它数值部分就是数值本身绝对值的二进制数 负数的原码是在其绝对值的基础上 最高位变为1 下面数值以1字节的大小描述 原码表示
  • 手把手教你实现一个向量

    文章目录 什么是向量 向量提供哪些接口 实现 宏定义 定义类 成员变量 构造函数与析构函数 构造函数 析构函数 成员函数 size get r put r e expand insert r e remove lo hi remove r
  • nodejs获取时间戳

    可以使用 JavaScript 内置的 Date 对象来获取当前的时间戳 可以使用 Date now 方法来获取当前的时间戳 consttimestamp Date now console log timestamp 也可以使用 Date
  • 轻松掌握Python自动化工具,解锁PyAutoGUI的强大功能

    前言 PyAutoGUI是一个用于图像识别和鼠标 键盘控制的Python库 它提供了一组函数和方法 用于自动化屏幕上的鼠标移动 点击 拖拽和键盘输入 以及执行图像识别和处理 本文旨在帮助读者入门 PyAutoGUI 理解其基础概念和掌握最佳
  • js逆向-国密SM2初探

    目录 前言 目标网站 加密分析 加密定位 结尾 本文仅供学习使用 切勿非法使用 如有侵权请联系作者及时删除 前言 无意中看到一个网站采用国密SM2算法进行登陆参数进行加密 之前接触的加密基本都是国外的算法 例如RSA DES MD5等等 国
  • 13位时间戳单位为毫秒,10位字符串单位为秒。时间戳转换日期数字格式100%全乎

    时间戳转换为年月日时分秒数字格式 注意时间戳有2种 13位时间戳 单位为毫秒 10位字符串 单位为秒 接口返回1616160878418 微秒 期望格式2021 03 19 21 34 35 标签 java new Date 变成GMT G
  • tar打包备份+ubuntu系统的修复

    如果ubuntu系统出问题 通过备份文件可以简单快速地修复ubuntu系统 tar打包十分必要 一 tar打包备份 1 进入管理员账户 sudo su 2 打包 tar cvPzf 20191203ubuntu1804 tgz exclud
  • 关于static 的各种数据类型 及在面向对象编程中的应用

    一 按存储区域分 全局变量 静态全局变量和静态局部变量都存放在内存的静态存储区域 局部变量存放在内存的栈区 1定义全局静态变量的好处 lt 1 gt 不会被其他文件所访问 修改 lt 2 gt 其他文件中可以使用相同名字的变量 不会发生冲突
  • 2023杭电暑假多校4 题解

    3 Simple Set Problem 题意 k 个多重集合 每个集合选出一个数形成新集合A 求 m a x A m
  • macos多合一系统安装u盘制作器_U 盘多系统安装盘制作神器YUMI

    通常我们一个 U 盘只能制作成一个系统安装盘 比如制作好一个 Windows 10 安装盘 日后想要用到 Linux WinPE 等安装盘时 只能重新制作一遍 非常浪费时间 而且现在 U 盘容量都很大 如果只放一个系统 同样就会白白浪费 U
  • 软考-操作系统

    考点梳理 进程管理 考点1 进程的状态 考法分析 本考点主要考查形式主要是根据图示判断相关状态位置或状态变迁条件 要点分析 操作系统三态模型如下图所示 操作系统五态模型 备考点拨 掌握操作系统三态模型 五态模型的状态位置及其状态变迁条件 考

随机推荐

  • arcgis 10.8 for win10安装教程

    本文主要记录arcgis安装步骤 遇到的问题等 文章目录 一 前提 二 下载与安装 1 下载 2 安装 参考资料 一 前提 下载前需要确定 1 ArcGIS对系统的要求 安装之前系统需安装 net framework 4 5 以上版本 我的
  • 【翻译】 WireGuard 何去何从?

    请考虑订阅 LWN订阅是 LWN net 的生命线 如果您喜欢这些内容并希望看到更多 您的订阅将有助于确保 LWN 继续蓬勃发展 请访问此页面加入我们 让 LWN 继续在网络上传播 作者 Jonathan Corbet 2019年3月25日
  • Angular2 之 单元测试

    单元测试需要掌握的知识点 karma conf js的配置 具体了解到每一项的意义 这样才能真正的了解这个配置是如何配置的 甚至才可以做到自己的配置 组件的测试 单独的service测试 Angular的测试工具 Angular的测试工具类
  • 飞机大战(C语言版)

    大一下要交课程设计 于是就用C语言写了一个飞机大战小游戏 没有用到第三方库 飞机和子弹的移动使用的光标移动函数 所以没有卡顿 其中w s a d分别表示上下左右 包括大写 空格发射子弹 游戏结束后可选择是否储存游戏数据 该程序复制后可直接使
  • git push错误: failed to push some refs to

    原因 当你在git上对它进行了在线修改 但是没有对本地库进行同步 这个时候你再次commit 想把本地库提交到远程git库中 就会出现push失败问题 简单来说 就是远程与本地存在不一致的commit情形 解决方法 确保远程代码没问题的情况
  • 【Java SE】抽象类和接口

    点进来你就是我的人了博主主页 戳一戳 欢迎大佬指点 欢迎志同道合的朋友一起加油喔 目录 前言 一 抽象类 1 抽象类的概述 2 抽象类特点 3 抽象关键字abstract和哪些不可以共存 4 抽象类的细节 5 抽象类的作用 二 接口 1 什
  • 统计学习方法论概念

    1 统计学习包含监督学习 非监督学习 半监督学习和强化学习 2 监督学习 监督学习的任务是学习一个模型 使模型能够根据任意给定的输入 对模型的输出做出一个好的预测 监督学习分为学习和预测两个过程 由学习系统和预测系统组成 3 损失函数和风险
  • 【C++】迭代器 && vector中迭代器失效

    文章目录 1 什么是迭代器 2 迭代器与指针 3 迭代器的分类 3 1具体分类 3 2为什么要对迭代器分类 3 3迭代器的使用建议 4 vector迭代器失效 4 1迭代器失效及其危害 4 2哪些操作会导致迭代器失效 如何解决 1 什么是迭
  • 视觉SLAM十四讲笔记-6-3

    视觉SLAM十四讲笔记 6 3 文章目录 视觉SLAM十四讲笔记 6 3 6 3 实践 曲线拟合问题 6 3 1 手写高斯牛顿法 6 3 2 使用Ceres进行曲线拟合 Ceres 简介 安装Ceres 使用Ceres拟合曲线 6 3 3
  • JAVA往map添加元素_java list map在初始化的时候添加元素

    List list new ArrayList add First Object add Second Object add Third Object Map map new HashMap put First Key First Valu
  • 初始OAuth2.0

    1 什么是OAuth2 0 OAuth2 0 是目前使用非常广泛的授权机制 用于授权第三方应用获取用户的数据 举例说明 用户可以通过选择其他登录方式来使用gitee 这里就使用到了第三方认证 OAuth 引入了一个授权层 用来分离两种不同的
  • vue 修改标题名字

    1 直接修改 在main js中添加 document title 大屏控制 2 根据路由动态改变 https www cnblogs com CinderellaStory p 10858035 html
  • iPhone苹果15手机怎么看是国行还是美版或港版的苹果iPhone15手机?

    iPhone苹果手机15机型区域版本识别代码 CH代码为国行 LL代码为美版 ZP代码为港版 iPhone苹果15手机怎么看是国行还是美版或港版的苹果iPhone15手机 1 打开苹果iPhone15手机桌面上的 设置 2 在iPhone苹
  • OWASP ZAP安装遇到Error.A JNI error has occurred ,please check your installation and try again

    问题描述 我当时下载的是兼容版本 下载完成后双击zap bat发现运行一下就闪退 然后运行jar文件就报错 过程 最开始以为是java环境的问题 后面用java version去运行了一下 发现java环境是正常的 但又一直提示java的问
  • 4大技术亮点支撑应用优势 全新一代旗舰型行业无人机千巡翼X4发布

    随着无人机与数字成像技术的发展 无人机航测成为了重要的地理信息采集手段 也越来越受重视 据相关研报数据统计 预计2025年我国实景三维在自然资源领域的 以数据采集 处理为主的直接市场规模预计将达40亿元 推测2025年关联市场规模将达400
  • MFC设置控件文本字体、大小、颜色、背景

    1 修改字体 大小 声明一个CFont类型的类成员变量 CFont m editFont 然后在类的初始化函数OnInitDialog 中添加以下两行代码 设置静态文本字体大小 m editFont CreatePointFont 180
  • MFC编程实验(三):组件(列表框元素的增删)

    一 实验要求 创建一个对话框应用程序 实现如下布局 完成如下功能 1 初始状态 列表中有4个元素 2 可以在编辑框中输入新朋友的名字 点击 添加 按钮添加到列表框 同时清空编辑框中的名字 3 选中列表框中的一个名字 点击 删除 按钮可以删除
  • GDB 简略手册

    杂项 命令 用法 说明 h elp help 显示可用帮助文档 h CMD 显示关于指定命令的帮助 apr opos apr REGEXP 使用正则表达式搜索命令 i nfo info 显示可展示的信息 ENTER 无命令回车 重复执行上一
  • 接口测试总结

    第一部分 主要从问题出发 引入接口测试的相关内容并与前端测试进行简单对比 总结两者之前的区别与联系 但该部分只交代了怎么做和如何做 并没有解释为什么要做 第二部分 主要介绍为什么要做接口测试 并简单总结接口持续集成和接口质量评估相关内容 第
  • 手写系列之--call/apply/bind/防抖/节流

    call call 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数 语法 function call thisArg arg1 arg2 JavaScript中由于函数的this指向它的直接调用者 我们变更调用者即