• JavaScript中的this指向规则
  • 源码来袭:call、apply手写实现与应用

理解建议:如果对this指向规则不了解的话,建议先了解this指向规则,最好还能对call和apply的使用和内部原理也有所了解,不然直接研究bind还是会有些难度的。

一、bind()的使用

//html
<button id="btn"></button>
//js
var list = {init:function(){this.ms = "duyi";this.dom = document.getElementById("btn");this.bindEvent();},bindEvent:function(){this.dom.onclick = this.showMessage.bind(this);},showMessage:function(){alert(this.ms);}
}
list.init();

在单对象编程中,有一种非常典型的bind()的应用,就以上面的示例来说,当出现给DOM绑定事件回调函数时,又还需要继续保持函数的this指向原来的对象,就可以按照示例的这种方式来实现:this.dom.onclick = this.showMessage.bind(this);

我们知道call和apply可以改变函数执行的this指向,但是call和apply都是立即执行该函数,而bind是将this指向绑定到指定的对象上,并且返回函数并维持this指向这个对象。接下来再来看看bind的参数设置示例:

function show(x,y,z,w){console.log(this,x,y,z,w);
}
var DuyiO = {x : 20
}
var newShow = show.bind(DuyiO,"1","2",3);
newShow(4);//Object {x: 20} "1" "2" 3 4

bind的参数和call非常类似,唯一的区别就在于除了调用bind时传入参数外,还可以在正式执行时传入参数,两次传入参数以拼接的方式作为函数执行的实参。但是需要注意的是,第一个参数作为函数的this指向对象必须要在调用bind方法时传入,如果调用bind方法不传入任何参数,函数的this指向就会绑定到window上。比如下面这种情况:

var newShow = show.bind();
newShow(DuyiO,"1","2",3,4);//Window {…} Object {x: 20} "1" "2" 3

最后还有一个基本上不会被应用到的功能,就是返回的函数被new关键字用来创建一个新的对象,而构造函数还是原函数本身(第二个示例中的show)。这个功能在模仿bind源码不能100%实现,但是也可以间接的实现其需要的功能。

二、bind手写实现

1.首先实现函数调用bind修改this指向即参数设置:

1 Function.prototype.MyBind = function(target){
2     var self = this;
3     var args = [].slice.call(arguments,1);
4     var f = function(){
5         return self.apply( target || window,args );
6     }
7     return f;
8 }

2.接着再来实现函数正式调用执行时传入设置:

1 Function.prototype.MyBind = function(target){
2     var self = this;
3     var args = [].slice.call(arguments,1);
4     var f = function(){
5         var _arg = [].slice.call(arguments,0);
6         return self.apply( target || window,args.concat(_arg) );
7     }
8     return f;
9 }

3.最后实现当返回函数被new操作符引用作为构造函数依然指向原函数(模拟实现功能):

 1 Function.prototype.MyBind = function(target){
 2     var self = this;
 3     var args = [].slice.call(arguments,1);
 4     var temp = function(){};
 5     var f = function(){
 6         var _arg = [].slice.call(arguments,0);
 7         return self.apply(this instanceof temp ? this : ( target || window ),args.concat(_arg) );
 8     }
 9     temp.prototype = self.prototype;
10     f.prototype = new temp();
11     return f;
12 }

这个模拟实现主要有两个关键点需要重点理解:

a.代码第七行中的this instanceof temp ? this : ( target || window ):当返回函数f被new作为构造函数引用时,这时候this指向了函数执行时内部隐式添加在变量对象上的this(这里不清楚的话可以参考JavaScript中的this指向规则),当然普通调用执行就是指向self。

b.代码第九行和第十行为什么需要改变f的原型,这就是我前面讲的模拟实现方法构造,我们知道bind在JS内部实现的是其返回函数还是那个原来的函数,这里我们多加了一层f来实现的,所以在函数被当做构造函数的时候,将f的原型指向self也可以实现其功能,但是构造的实例对象是基于f实现的,最终构造原型链还是指向self原型,该有的方法属性依然都会有。只是在原型链上多了f这个包装层。

转载于:https://www.cnblogs.com/ZheOneAndOnly/p/10423825.html

源码来袭:bind手写实现相关推荐

  1. ArrayList源码分析与手写

    本节主要分析JDK提供的ArrayList的源码,以及与自己手写的ArrayList进行对比. ArrayList源码分析 构造方法 private static final int DEFAULT_ ...

  2. 【详解】Ribbon 负载均衡服务调用原理及默认轮询负载均衡算法源码解析、手写

    Ribbon 负载均衡服务调用 一.什么是 Ribbon 二.LB负载均衡(Load Balancer)是什么 1.Ribbon 本地负载均衡客户端 VS Nginx 服务端负载均衡的区别 2.LB负 ...

  3. 播放失败246106异常代码_web前端面试题:您能读懂的Promise源码实现(手写代码)...

    Promise 是 web 前端工程师在面试的过程中很难绕过的一个坎.如果您目前处于对 Promise 一知半解,或仅仅是停留在可以使用的层面上,建议您跟着本文敲打练习一遍,相信您一定会有所收获!另外 ...

  4. web前端面试题:你能读懂的Promise源码实现(手写代码)

    Promise是web前端工程师在面试的过程中很难绕过的一个坎.如果您目前处于对Promise一知半解,或仅仅是停留在可以使用的层面上,建议您跟着本文敲打练习一遍,相信您一定会有所收获!另外文章有点长 ...

  5. 修复版ZFAKA发卡系统源码 自适应PC+手机端

    介绍: 2021年12月修复版ZFAKA系统源码 自适应PC+手机端 带视频搭建教程 主要修复了接口问题 测试环境:Linux环境:Nginx 1.20.1-MySQL 5.6.50-PHP-7.1 ...

  6. PHP响应式H5图片网盘外链系统源码 自适应PC手机端

    介绍: PHP响应式H5图片网盘外链系统源码 自适应PC手机端 支持图片违规检测 网盘与外链分享步伐,撑持一切格局文件的上传,可以天生文件外链.图片外链.音乐视频外链,天生外链同时主动天生响应的UBB ...

  7. java qq聊天界面_【附源码】用Java写了一个类QQ界面聊天小项目,可在线聊天!...

    原标题:[附源码]用Java写了一个类QQ界面聊天小项目,可在线聊天! 目录: 1.功能实现 2.模块划分 3.使用到知识 4.部分代码实现 5.运行例图 1.功能实现 1.修改功能(密码.昵称.个性 ...

  8. 知道系统源码/知识问答系统源码/完整PC+手机端带功能强大后台管理系统

    仿百度知道系统源码,知识问答系统源码,带有完整的PC端.手机端界面,功能强大后台管理,非常适用于垂直问答社区类行业网站使用. 阿国简单测试了一下,系统功能比较完善,界面部门需要简单优化一下,整体还是很 ...

  9. PHP绿茶小说站群网站源码 自适应pc+手机端

    介绍: PHP绿茶小说站群网站源码 自适应电脑+手机端+秒收隔天速出权重 绿茶小说站群2.x-秒收隔天速出权重-小说流量稳定收割机-精品轻量级PHP站群系统站群系统,小说行业专用引流精品站群,绿茶小说 ...

最新文章

  1. LeetCode简单题之长按键入
  2. 纯jsp实现评论功能_基于云开发的小程序版本更新、评论功能改进、后台管理的实现...
  3. python面向接口编程_Python 中的面向接口编程
  4. java 403怎么抛出_django主动抛出403异常的方法详解
  5. startuml动态模型工具_动态面板模型估计方法简介以及stata应用
  6. [转载] java自定义异常类以及全局log打印
  7. vscode C++配置opencv
  8. JAVA超市管理系统
  9. 开头的单词_学Z字母本义和引申义,初高中Z开头的单词几分钟全部轻松记忆!...
  10. 抗扰度试验--EMS--电压暂降、短时中断--DIP
  11. 【C++笔试强训】第三天
  12. LapSRN tensorflow版本环境配置
  13. 【前端升全栈】 五分钟了解Node.js
  14. 矩阵/向量/标量间相互求导
  15. 软件构造课程面向对象编程学习心得
  16. 昆仑万维:如涵在纳斯达克挂牌 公司持有其3.91%股权
  17. PHP(2):PHP读取MS Sql Server 2014数据库数据
  18. 174.127.195.176/bbs/index.php,[原创]一次逆向fb寻找密码的记录及还原相关算法
  19. 让页面滑动流畅得飞起的新特性:Passive Event Listeners
  20. php背景特效代码,JS和CSS实现渐变背景特效的代码

热门文章

  1. 写给准备找工作的同志们!!!!(转载)
  2. 搜索引擎学习(一)初识Lucene
  3. 中文自然语言处理(NLP)(三)运用python jieba模块计算知识点当中关键词的词频
  4. 50 【Go版本变化】
  5. 【8086汇编-Day6】关于loop的实验
  6. Oracle分析函数-OLAP函数总结
  7. nhibernate3 linq的的select 操作
  8. asp.net 页面static变量问题
  9. 不可多得的Javascript(AJAX)开发工具 - Aptana
  10. android代码设置全屏