手动实现 call、apply、bind

2023-11-17

手动实现 call、apply、bind

改变 this的指向,就是将函数fn放入传入的context中,然后执行context[fn](),此时的fn中的this就变成了context,在函数执行完毕之后,需删除context中的fn

call

  1. 判断当前 this 是否为函数,防止 Function.prototype.myCall()直接调用
  2. context为可选参数,如果不传的话默认上下文为 window
  3. 为 context 创建一个 Symbol(保证不会重名)属性,将当前函数赋值给这个属性
  4. 处理参数,传入第一个参数后的其余参数
  5. 调用函数后即删除该 Symbol 属性
Function.prototype.myCall = function(context = window, ...args) {
    if (this === Function.prototype) {
        return undefined; // 用于防止 Function.prototype.myCall() 直接调用
    }
    context = context || window;
    const fn = Symbol();
    context[fn] = this;
    const result = context[fn](...args);
    delete context[fn];
    return result;
};

apply

apply 实现类似 call,参数为数组

Function.prototype.myApply = function(context = window, args) {
    if (this === Function.prototype) {
        return undefined; // 用于防止 Function.prototype.myCall() 直接调用
    }
    const fn = Symbol();
    context[fn] = this;
    let result;
    if (Array.isArray(args)) {
        result = context[fn](...args);
    } else {
        result = context[fn]();
    }
    delete context[fn];
    return result;
};

bind

因为 bind()返回一个方法需手动执行,因此利用闭包实现。

Function.prototype.myBind = function(context, ...args1) {
    if (this === Function.prototype) {
        throw new TypeError('Error');
    }
    const _this = this;
    return function F(...args2) {
        // 判断是否用于构造函数
        if (this instanceof F) {
            return new _this(...args1, ...args2);
        }
        return _this.apply(context, args1.concat(args2));
    };
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

手动实现 call、apply、bind 的相关文章

  • 数据结构——链表一网打尽

    目录 前言 函数的传参 不带头单向非循环链表 带头双向循环链表 顺序表与链表的优缺点 单链表源码 带头双向循环链表源码 前言 链表是一种物理存储结构上非连续非线性的结构 数据元素的逻辑顺序通过指针次序链接实现 在逻辑结构上好像通过链子链接起

随机推荐

  • html编译器推荐

    学习html 这种简单的网页语言 我推荐大家使用 Sublime Text 代码编译器 本人是个痛快之人 推荐理由简单说 一 编译窗口看着舒服 代码自带颜色 是种高大上的美 二 功能强大 强大到你目前学习html不用以你现在的水平去担心功能
  • C++:map和set

    一 set 1 set的介绍 set 是一个Key模型的搜索二叉树 include
  • DevExpress WinForms图表组件 - 直观的数据信息呈现新方式!(一)

    凭借界面控件DevExpress WinForms全面的2D和3D图表类型的集合 DevExpress WinForms的图表控件设计大大简化了开发者直观地向最终用户呈现信息的方式 DevExpress WinForms有180 组件和UI
  • [现代控制理论]5_系统的可控性_controllability

    现代控制理论 11 现代控制理论串讲 完结 pdf获取 现代控制理论 10 可观测性与分离原理 观测器与控制器 现代控制理论 9 状态观测器设计 龙伯格观测器 现代控制理论 8 5 线性控制器设计 轨迹跟踪simulink 现代控制理论 8
  • Ubuntu20.04如何卸载软件

    自此换了Ubuntu系统 很多用起来特别不顺手 例如现在删个软件 window系统右击强制删除就完了 现在都不知道咋整 gt lt 特此整理了如下几种情况 希望能帮到跟我一样状况的小伙伴O O 手动卸载 点击 设置 应用程序 选中自己要卸载
  • 手把手带你撸zookeeper源码系列目录

    手把手带你撸zookeeper源码 前言 手把手带你撸zookeeper源码 配置文件 手把手带你撸zookeeper源码 如何启动一个zookeeper服务 手把手带你撸zookeeper源码 从源码角度分析zookeeper启动时都做了
  • Linux系统之Centos安装epel源

    Linux系统之Centos安装epel源 一 检查本地系统环境 1 检查系统版本 2 检查系统内核版本 二 检查yum仓库 1 查看repo文件 2 检查yum仓库的状态 三 安装epel源 1 查看系统epel release noar
  • 【论文笔记_目标检测_2022】Cross Domain Object Detection by Target-Perceived Dual Branch Distillation

    基于目标感知双分支提取的跨域目标检测 摘要 在野外 跨领域目标检测是一项现实而具有挑战性的任务 由于数据分布的巨大变化和目标域中缺乏实例级注释 它的性能会下降 现有的方法主要关注这两个困难中的任何一个 即使它们在跨域对象检测中紧密耦合 为了
  • arcgis不闭合线转面_ArcGIS不闭合线转面

    ArcGIS不闭合线转面 1 打开ArcMap用Add Data加载shp Polyline线文件 2 选Editor编辑 Start Editing开始编辑 3 选Editor编辑 More Editing Tools Topology拓
  • java:hashMap: get(null)引发的对其数据结构具体形态的思考

    ref 原文 https blog csdn net fenglongmiao article details 79656198 note 我们知道HashMap集合是允许存放null值的 hashMap是根据key的hashCode来寻找
  • 软工导论知识框架(五)面向对象方法学

    传统软件工程方法学适用于中小型软件产品开发 面向对象软件工程方法学适用于大型软件产品开发 一 四要素 对象 类 继承 传递消息实现通信 二 概念 1 对象 具有相同状态的一组操作的集合 对状态和操作的封装 2 类 对具有相同状态和相同操作的
  • 带你手写基于 Spring 的可插拔式 RPC 框架(三)通信协议模块

    在写代码之前我们先要想清楚几个问题 我们的框架到底要实现什么功能 我们要实现一个远程调用的 RPC 协议 最终实现效果是什么样的 我们能像调用本地服务一样调用远程的服务 怎样实现上面的效果 前面几章已经给大家说了 使用动态代理 在客户端生成
  • CentOS7中安装mysql

    1 确保本机的mysql已经卸载干净 需要将mariadb和mysql全部卸载 rpm qa grep i mariadb rpm qa grep i mysql 使用rpm ev nodeps 命令将查询出来的文件逐一卸载 sudo rp
  • Docker Compose、Docker Swarm (docker进阶 狂神)

    文章目录 Docker Compose 安装 开源项目 博客 实战 自己编写微服务上线 Docker Swarm 四台机器安装docker环境 Swarm集群搭建 Raft协议 体会 灰度发布 金丝雀发布 其他命令学习方式 Docker C
  • notepad++以16进制查看文件

    1 Notepad 可以编辑PE文件 二进制文件即HEX码 2进制 16进制都可以 通过附加的组件HexEditor即可实现 另外一款Notepad 自带插件TextFX也有这个功能 但实现效果不如Hex Editor 下载地址 https
  • CH1-绪论

    文章目录 算法时间复杂度的计算 一 冒泡排序简介 从小到大排序 算法时间复杂度的计算 我们一般只关心随着问题规模n趋于无穷时 函数中对函数结果影响最大的项 比如说 T n 3n 3 当n非常大的时候 常数3和n的系数3对函数结果的影响就很小
  • vue--综合组件间的通信

    二 综合组件之间的通信 实现一个ToDoList 完成所有的组件的创建和使用 add点击add按钮时候 将用户输入的内容 todoinput 显示在 todolist 核心代码 兄弟组件间通信 步骤1 var bus new Vue 步骤2
  • QT210烧写UBOOT到SD卡原理以及UBOOT启动

    原文地址 http blog csdn net shushi0123 article details 8018998 世界早已进入cortex a8了 我也得跟进一下所以买了QT210的开发板 长话短说开始搞SD卡烧写UBOOT 从SD启动
  • TCP选项之SO_LINGER

    SO LINGER这个选项在我以前带队改造haproxy的时候引出过一个reset RST 客户端连接的bug SO LINGER作用 设置函数close 关闭TCP连接时的行为 缺省close 的行为是 如果有数据残留在socket发送缓
  • 手动实现 call、apply、bind

    手动实现 call apply bind 改变 this的指向 就是将函数fn放入传入的context中 然后执行context fn 此时的fn中的this就变成了context 在函数执行完毕之后 需删除context中的fn call