bind的原理和bind的实现

2023-10-31

一、bind的特性

  1. 传递的第一个参数做为调用它的函数的this指向(bind可传递若干参数)。
  2. 若第一个参数传递基础数据类型,则调用他的函数的this指向该基础数据类型的包装类实例化对象。
  3. 若第一个参数为null或undefined,则调用他的函数的this指向window。
  4. bind的第二个之后的参数为调用它的函数的参数列表。
  5. bind方法会返回一个新的方法,并且该方法满足柯里化,仍可以传递参数,但这个方法的this不可被call、apply、bind改变。
  6. bind方法返回的新方法,如果使用new实例化,那么原本通过bind绑定的this指向的对象会失效,this将指向到新实例化的对象上,且可以使用原方法原型链上的属性或方法。

二、初步模拟实现(未实现new)

这里的对返回的新方法实例化后,this没有指向新实例化的对象,即未实现bind的第6个特性。

			// this将指向的对象
            const obj = {
                name: '我是obj'
            }
            // 测试方法
            function sayHello(age, sex, hobby) {
                this.hobby = hobby
                console.log("我的this指向:", this);
                console.log(`Hello, ${this.name}, age: ${age}, sex: ${sex}, hobby: ${hobby}`);
            }
            // 测试方法的原型上的属性
            sayHello.prototype.fater = '我爸是Function';
            // 使用原bind方法
            const fun = sayHello.bind(obj, 32, 'male');
            // 实例化原bind方法返回的函数
            const f = new fun('female');
            // 输出【测试方法sayHello】的原型上的属性
            console.log('原bind返回方法实例化后使用【测试方法sayHello】的原型上的属性:', f.fater);
            // 初步模拟方法bind方法--------------
            Function.prototype.myBind = function (object) {
                // 记录this,后需返回普通方法后,this指向调用者,更多关于this可以看这里:https://blog.csdn.net/Kindergarten_Sir/article/details/109909886
                const that = this;
                // const arg = Array.prototype.slice.apply(arguments, [1]);  // 截取arguments参数列表除第一个以外的参数,与下面es6方法效果相同
                const [, ...arg] = arguments; // arguments是参数列表,这是es6的解构语法,拿到除第一个参数以外的参数
                return function () {
                    // 下面的arguments是返回的这个方法的arguments,这主要是为了模拟【原bind返回方法可传参】
                    that.apply(object, [...arg, ...arguments]);
                }
            }
            // 使用自定义myBind
            const newFun = sayHello.myBind(obj, 32, 'male');
            // 实例化自定义myBind方法返回的函数
            var nf = new newFun('female');
            console.log('自定义myBind返回方法实例化后使用【测试方法sayHello】的原型上的属性:', nf.fater)

测试结果:
在这里插入图片描述

三、完善myBind

关键点

  1. 之前内部返回的方法是普通函数,所以this满足谁定义指向是的特点,所以可以使用instanceof检测有没有使用new。(instanceof用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链
  2. 将内部返回的函数变为具名函数,且将返回函数的原型指向原函数的原型。
 			// this将指向的对象
            const obj = {
                name: '我是obj'
            }
            // 测试方法
            function sayHello(age, sex, hobby) {
                this.hobby = hobby
                console.log("我的this指向:", this);
                console.log(`Hello, ${this.name}, age: ${age}, sex: ${sex}, hobby: ${hobby}`);
            }
            // 测试方法的原型上的属性
            sayHello.prototype.fater = '我爸是Function';
            // 使用原bind方法
            const fun = sayHello.bind(obj, 32, 'male');
            // 实例化原bind方法返回的函数
            const f = new fun('female');
            // 输出【测试方法sayHello】的原型上的属性
            console.log('原bind返回方法实例化后使用【测试方法sayHello】的原型上的属性:', f.fater);
            // 完善模拟方法bind方法--------------
            Function.prototype.myBind = function (object) {
                // 记录this,后续返回普通方法后,this指向调用者,更多关于this可以看这里:https://blog.csdn.net/Kindergarten_Sir/article/details/109909886
                // 这里的this是调用myBind方法的函数。
                const that = this;
                // const arg = Array.prototype.slice.apply(arguments, [1]);  // 截取arguments参数列表除第一个以外的参数,与下面es6方法效果相同
                const [, ...arg] = arguments; // arguments是参数列表,这是es6的解构语法,拿到除第一个参数以外的参数
                const newFun = function () {
                    // 普通函数this满足谁调用指向谁的特点,所以可以使用instanceof检测有没有使用new。
                    if (this instanceof newFun) {
                        // 如果是使用new实例化,则this指向新的实例化对象,这里的this本身就满足谁调用指向谁的特点,所以直接传递this就指向了实例化后的对象
                        // 下面的arguments是返回的这个方法的arguments,这主要是为了模拟【原bind返回方法可传参】
                        that.apply(this, [...arg, ...arguments]);
                    } else {
                        // 如果不是使用new实例化的,那么就要将函数的this指向到通过myBind传递的对象上。
                        // 下面的arguments是返回的这个方法的arguments,这主要是为了模拟【原bind返回方法可传参】
                        that.apply(object, [...arg, ...arguments]);
                    }
                }
                // 将内部返回的函数变为具名函数,且将返回函数的原型指向原函数的原型。
                newFun.prototype = that.prototype;
                // 返回方法
                return newFun
            }
            // 使用自定义myBind
            const newFun = sayHello.myBind(obj, 18, 'male');
            // 实例化自定义myBind方法返回的函数
            var nf = new newFun('female');
            console.log('自定义myBind返回方法实例化后使用【测试方法sayHello】的原型上的属性:', nf.fater)

测试结果:
在这里插入图片描述
call的实现点这里

apply的实现点这里

如果对你有帮助可以

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

bind的原理和bind的实现 的相关文章

  • 利用python建立股票量化交易系统(一)——小市值选股票模型

    从今天开始正式开启我的博客之旅 博客内容全部是我自己的量化心得 主要还是为自己将来中工作之中遇到相似问题 可以方便的找到答案 如果能帮到有相似问题的其他同学 我也很开心 如果帮不到的话 不喜勿喷 如果文章中有什么不对的地方 欢迎批评指正 建
  • 新版QQ代挂系统源码四套模板

    介绍 代挂源码 代挂对接教程源码已简洁版优化框架数据 对接代挂教程均在 压缩文件里 源码进行了优化 原后门已清楚掉 上传源码解压即可安装访问网址 网盘下载地址 https zijiewangpan com VylBgT70aLu 图片
  • 连接Charles后,小程序无法打开,提示“运行失败”解决方法

    今天在使用Charles抓包的过程中 手机端安装了证书 并且证书安装成功 使用手机浏览器可以正常抓包 但是在使用微信打开小程序准备测试时 无法打开 并且提示 运行环境失败 于是做了以下几个操作 最后可以成功抓包 1 微信版本升级 将微信卸载

随机推荐

  • Java代码中如何判断一个HashMap对象是否为空呢?

    转自 Java代码中如何判断一个HashMap对象是否为空呢 下文讲述检测HashMap集合对象是否无元素的方法分享 如下所示 实现思路 使用isEmpty方法即可检测HashMap中的元素是否为空 isEmpty 语法 hashmap i
  • 学习Javascript的书籍

    原文地址 http www ruanyifeng com blog 2008 01 javascript book recommendation html 作者 阮一峰 日期 2008年1月 9日 昨天 ppip同学留言 你的js主要是用什
  • SQL Server(2019)数据库----数据查询(数据库系统概论第五版)

    目录 一 课本例题查询 1 查询全体学生的姓名及其出生年份 2 查询全体学生的姓名 出生年份和所在的院系 要求用小写字母表示系名 3 查询选修了课程的学生学号 4 查询不是数学系 计算机系学生的姓名和性别 5 查询选修了3号课程的学生的学号
  • Redis面试题(四)

    文章目录 前言 一 锁互斥机制 二 watch dog 自动延期机制 三 可重入加锁机制 四 释放锁机制 五 上述 Redis 分布式锁的缺点 六 使用过 Redis 分布式锁么 它是怎么实现的 总结 前言 锁互斥机制 watch dog
  • QT中信号与槽的连接

    本文章主要通过代码的形式讲解QT中connect函数对于信号和槽函数的连接 include mainwindow h include ui mainwindow h include
  • 搞事情之使用七牛云的注意事项

    原文地址 PJ 的 iOS 开发日常 前言 本博客最初所采用的图床就是七牛 当时因为第一次使用图床之类的服务 没有进行一个比较好的筛选 并且没有考虑过多的细节 所以直接采用了七牛 经过一段时间后 因为博客访问量上去了 超出七牛每月的免费流量
  • C++ malloc/free/new/delete详解(内存管理)

    这里写目录标题 malloc free 典型用法 内存分配 实现过程 brk和mmap 申请小于128k的内存 申请大于128k的内存 释放内存 brk和mmap的区别 new delete 典型用法 内存分配 实现过程 new delet
  • 生信入门(六)——单细胞分析(Seurat)

    生信入门 六 单细胞分析 Seurat 文章目录 生信入门 六 单细胞分析 Seurat 一 数据导入 1 数据来源 2 数据导入 二 标准预处理 1 QC和选择细胞进行进一步分析 2 规范化数据 3 识别高度可变的特征 特征选择 4 缩放
  • Win10家庭版安装Docker for windows遇坑总结

    Win10家庭版安装Docker for windows遇坑总结 安装前的简单了解 安装步骤 添加Hyper v 安装Docker for windows 其他问题 因为做毕设需要结合本组学长开发的系统 不得已开始入坑学习docker 遇到
  • 程序员面试题精选100题(44)-数值的整数次方

    程序员面试题精选100题 44 数值的整数次方 题目 实现函数double Power double base int exponent 求base的exponent次方 不需要考虑溢出 方法一 由于输入的exponent是个int型的数值
  • AR-虚实融合文献阅读整理(二)

    一 增强现实中虚实融合和人机交互技术的研究与应用 黄震宇 基于标志物的识别 利用opencv和三维图形引擎OGRE实现虚实融合展示系统 人机交互方案采用PrimeSense的深度摄像头 通过计算机视觉处理 重建了人体三维谷歌系统定义体感语义
  • C++:CMake常用变量【CMAKE_CXX_FLAGS、CMAKE_BUILD_TYPE、×_BINARY_DIR】

    CMake共用七种变量 如下所示 提供信息的变量 控制变量 描述系统的变量 控制构建过程的变量 语言变量 CTest变量 CPack变量 一 CMake变量引用的方式 使 进 变量的引 在 IF 等语句中 是直接使 变量名 不通过 取值 二
  • Linux系统中/etc/rc.local和/etc/rc.d/rc.local的区别

    etc rc d rc local 用于添加开机启动命令 etc rc local是 etc rc d rc local的软连接 转载于 https www cnblogs com Samuel Leung p 10477162 html
  • 【Spring

    上文讲了 Spring 资源处理 本文讲一下resource的扩展接口相关 资源处理扩展 ResourceLoader 接口 定义 图解 示例 策略 ResourcePatternResolver接口 ResourceLoaderAware
  • 实例修改类属性python_Python类属性和实例属性的优先级

    可以看到 属性可以分为类属性和实例属性 那么问题就来了 如果类属性和实例属性名字相同时 会怎么样 这就涉及Python中类属性和实例属性的优先级的问题了 我们可以做一个实验 在前面类定义的基础上 在实例属性中 也初始化一个localtion
  • DS18B20温度传感器原理及使用教程

    1 芯片简介 DS18B20数字温度传感器提供9 Bit到12 Bit的摄氏温度测量精度和一个用户可编程的非易失性且具有过温和低温触发报警的报警功能 DS18B20采用的1 Wire通信即仅采用一个数据线 以及地 与微控制器进行通信 该传感
  • Linux下安装/使用mariadb

    文章目录 第一章 mariadb在rhel7上的使用 第二章 mariadb在rhel6上的安装 1 编译源码包 比较慢 2 二进制包安装 比较推荐 第一章 mariadb在rhel7上的使用 rhel7及以上系统默认安装了mariadb
  • C#基础入门之数据类型

    一 值类型和引用类型 在C 中数据类型总共可以分为两类 分别是值类型和引用类型 值类型 表示复制一个当前变量传给方法 当你在这个方法中改变这个变量的值时 最初生命的变量的值不会变 引用类型 表示你操作的数据是同一个 也就是说当你传一个参数给
  • 物联网面试必过要点

    要是能熟记以下知识点 再加上自身的项目经验 过个面试 问题不大 指针定义 一个指向指针的的指针 它指向的指针是指向一个整型数 int a 一个有10个指针的数组 该指针是指向一个整型数的 int a 10 一个指向有10个整型数数组的指针
  • bind的原理和bind的实现

    一 bind的特性 传递的第一个参数做为调用它的函数的this指向 bind可传递若干参数 若第一个参数传递基础数据类型 则调用他的函数的this指向该基础数据类型的包装类实例化对象 若第一个参数为null或undefined 则调用他的函