一、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 = hobbyconsole.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/109909886const 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]);}}// 使用自定义myBindconst 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 = hobbyconsole.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}// 使用自定义myBindconst newFun = sayHello.myBind(obj, 18, 'male');// 实例化自定义myBind方法返回的函数var nf = new newFun('female');console.log('自定义myBind返回方法实例化后使用【测试方法sayHello】的原型上的属性:', nf.fater)

测试结果:

call的实现点这里

apply的实现点这里

如果对你有帮助可以

bind的原理和bind的实现相关推荐

  1. 学习 koa 源码的整体架构,浅析koa洋葱模型原理和co原理

    前言 这是学习源码整体架构系列第七篇.整体架构这词语好像有点大,姑且就算是源码整体结构吧,主要就是学习是代码整体结构,不深究其他不是主线的具体函数的实现.本篇文章学习的是实际仓库的代码. 学习源码整体 ...

  2. Mybatis插件原理和PageHelper结合实战分页插件(七)

    今天和大家分享下mybatis的一个分页插件PageHelper,在讲解PageHelper之前我们需要先了解下mybatis的插件原理.PageHelper 的官方网站:https://github ...

  3. HBase学习指南之HBase原理和Shell使用

    HBase学习指南之HBase原理和Shell使用 参考资料: 1.https://www.cnblogs.com/nexiyi/p/hbase_shell.html,hbase shell 转载于: ...

  4. IAP的原理和stm8的IAP

    一.引出(IAP的原理和stm8上实现IAP的问题) 具有IAP功能的单片机,程序可以分为两部分:IAP和APP.APP是用来实现真正功能的程序,而IAP是用来远程重新编程APP的程序.单片机上电时会 ...

  5. 单链表反转的原理和python代码实现

    链表是一种基础的数据结构,也是算法学习的重中之重.其中单链表反转是一个经常会被考察到的知识点. 单链表反转是将一个给定顺序的单链表通过算法转为逆序排列,尽管听起来很简单,但要通过算法实现也并不是非常容 ...

  6. 计算机网络原理和OSI模型与TCP模型

    计算机网络原理和OSI模型与TCP模型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.计算机网络的概述 1.计算机网络的定义 计算机网络是一组自治计算机的互连的集合 2.计算机 ...

  7. HTTPS原理和CA证书申请

    转载自:HTTPS原理和CA证书申请(满满的干货) 众所周知,WEB服务存在http和https两种通信方式,http默认采用80作为通讯端口,对于传输采用不加密的方式,https默认采用443,对于 ...

  8. class加载原理和Dex加载的原理-----android插件化技术

    2019独角兽企业重金招聘Python工程师标准>>> class加载原理和Dex加载的原理 转载于:https://my.oschina.net/quguangle/blog/15 ...

  9. 转载椭圆曲线原理和openssl命令操作

    原文地址:https://www.johannes-bauer.com/compsci/ecc/ 椭圆曲线原理和openssl命令操作

最新文章

  1. 实验六 快速生成树配置
  2. 102. 二叉树的层序遍历 golang
  3. QT+PCL+VTK 一个点云显示和处理软件
  4. 如何创建带有.的文件夹
  5. 【软考软件评测师】2018年下案例分析历年真题
  6. 乱码(四): 撬动地球的支点
  7. CSS字体设置中常用字体大全
  8. c51汇编语言如何定义全局变量_汇编语言程序访问C语言全局变量
  9. 统计学、机器学习、数据挖掘、深度学习的关系
  10. 揭秘win10系统CPU占用100%的真正原因/找出那些罪魁祸首
  11. oracle 字段名中有空格 的查询
  12. 内核的同步机制(原子锁)
  13. 朋友圈发图多大不会被压缩_微信:朋友圈照片自动压缩 不暴露位置信息
  14. 【原创】图像处理第5弹:面部表情识别--微笑
  15. 临终关怀?抑或一切照旧?PR咋又更新了?
  16. 股票入门基础知识|游资或者庄股出货的结构形态
  17. 个人电脑应用常识记录
  18. php爬取房源,用python爬取二手房交易信息并进行分析
  19. java poi写入excel_Java使用POI读取和写入Excel指南
  20. 如何免费安装并激活序列号iMazing软件

热门文章

  1. 小明的字符串--牛客
  2. Make It a Chorus: Knowledge- and Time-aware Item Modeling for Sequential Recommendation sigir 20
  3. 汇编程序:将字符串倒序输出
  4. MyBatis插件:通用mapper的配置和应用
  5. 聊聊 Bladed 软件
  6. Oracle分区表概述、分类、使用方法及注意事项
  7. 申请GOOGLE的企业邮局
  8. matlab画波动图像,【基于Matlab的波动方程的可视化实现最终版材料】
  9. 菜鸟窝-仿京东淘宝项目学习笔记(二)ToolBar的基本使用
  10. linux菜鸟基础学习(一)