如何手动实现es5中的bind方法详解


Posted in Javascript onDecember 07, 2018

前言

this的指向在javascript中一直是个谜一样的存在,但是很多地方又会用到this,所以理解和使用this非常重要,关于this的理解这篇文章不做介绍,因为这篇的目的是改变this的指向。

改变this的指向有三种方法,call,apply,bind。下面先介绍下这三种方法,话不多说了,来一起看看详细的介绍吧

改变this指向

call

var a = {
 name:"aaa",
 say(type){
  console.log(type,this.name);
 }
}
a.say("at");//at aaa
var tn = {name:"ttt"};
a.say.call(tn,"tt")//tt ttt

可以看到通过call,say方法中的this指向了tn,传参的方式的列举

apply

var a = {
 name:"aaa",
 say(type){
  console.log(type,this.name);
 }
}
a.say("at");
var tn = {name:"ttt"};
a.say.apply(tn,["tt"])

可以看到通过apply,say方法中的this指向了tn,传参的方式是数组

bind

bind也能改变this的指向,不过和call,apply不同的地方在于,bind只改变this,不会指向函数

var a = {
 name:"aaa",
 say(type){
  console.log(type,this.name);
 }
}
var tn = {name:"ttt"};
var b = a.say.bind(tn);
b();//ttt

bind 改变this,也是能够继承原型链的,看下下面的代码

var to = {name:"to",color:"red"};
function Animal(){
 console.log(`name:${this.name}...color:${this.color}`);
}
Animal.prototype.say = function(){
 console.log(`say..name:${this.name}...color:${this.color}`);
}
var Cat = Animal.bind(to);
Cat();//name:to...color:red
var cat = new Cat();// name:undefined...color:undefined
cat.say();//say..name:undefined...color:undefined

因为cat是Cat的实例,Cat是改变了this的Animal,所以cat也是Animal的实例,但是this是指向cat的,所以this.name是undefined

实现bind

Function.prototype.bind = function(obj){
 const args = Array.prototype.slice.call(arguments,1);//保留bind时的参数
 const that = this;
 const bound = function(){
  const inArgs = Array.prototype.slice.call(arguments);//执行bind的函数时的参数
  const newArgs = args.concat(inArgs);//组装参数
  that.apply(obj,newArgs);//执行bind的函数
 }
 //继承prototype--寄生组合式继承
 function F(){};
 F.prototype = that.prototype;
 bound.prototype = new F();
 return bound;
}

然后执行上面的代码

Cat();//name:to...color:red
var cat = new Cat();//name:to...color:red
cat.say();//say..name:undefined...color:undefined

不过第二行和原生的bind还是有点区别的,这里还是记住了之前的bind的对象,原生的不知道为啥是undefined

面试题

实现es5中的bind方法,使得下面的代码输出success

function Animal(name,color){
 this.name = name;
 this.color = color;
}
Animal.prototype.say = function(){
 return `i am a ${this.color} ${this.name}`
}
const Cat = Animal.bind(null,"cat");
const cat = new Cat("white");
if(cat.say() === 'i am a white cat' && cat instanceof Cat && cat instanceof Animal){
 console.log("success")
}

加上上面的bind实现,咦??没有出现success??为什么?

分析一下代码,bind的第一个参数是null??null的时候应该默认为this,修改代码如下

Function.prototype.bind = function(obj){
 const args = Array.prototype.slice.call(arguments,1);//保留bind时的参数
 const that = this;
 const bound = function(){
  const inArgs = Array.prototype.slice.call(arguments);//执行bind的函数时的参数
  const newArgs = args.concat(inArgs);//组装参数
  const bo = obj || this;
  that.apply(bo,newArgs);//执行bind的函数
 }
 //继承prototype--寄生组合式继承
 function F(){};
 F.prototype = that.prototype;
 bound.prototype = new F();
 return bound;
}

输出success

完美~~~

撒花~~~

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
JavaScript 学习笔记(六)
Dec 31 Javascript
javascript函数以及基础写法100多条实用整理
Jan 13 Javascript
简介JavaScript中用于处理正切的Math.tan()方法
Jun 15 Javascript
JS去除空格和换行的正则表达式(推荐)
Jun 14 Javascript
angularJS 如何读写缓冲的方法(推荐)
Aug 06 Javascript
Node.js 实现简单小说爬虫实例
Nov 18 Javascript
jQuery读取XML文件的方法示例
Feb 03 Javascript
JavaScript实现一个空中避难的小游戏
Jun 06 Javascript
node.js之基础加密算法模块crypto详解
Sep 11 Javascript
提升node.js中使用redis的性能遇到的问题及解决方法
Oct 30 Javascript
详解原生JS动态添加和删除类
Mar 26 Javascript
layer插件实现在弹出层中弹出一警告提示并关闭弹出层的方法
Sep 24 Javascript
JavaScript时间与时间戳的转换操作实例分析
Dec 07 #Javascript
vue+SSM实现验证码功能
Dec 07 #Javascript
详解如何为你的angular app构建一个第三方库
Dec 07 #Javascript
JS实现随机生成10个手机号的方法示例
Dec 07 #Javascript
angular学习之动态创建表单的方法
Dec 07 #Javascript
JavaScript栈和队列相关操作与实现方法详解
Dec 07 #Javascript
微信小程序实现两边小中间大的轮播效果的示例代码
Dec 07 #Javascript
You might like
使用PHP模拟HTTP认证
2006/10/09 PHP
实战mysql导出中文乱码及phpmyadmin导入中文乱码的解决方法
2010/06/11 PHP
PHP开发的文字水印,缩略图,图片水印实现类与用法示例
2019/04/12 PHP
利用PHP计算有多少小于当前数字的数字方法示例
2020/08/26 PHP
JavaScript入门教程(12) js对象化编程
2009/01/31 Javascript
JavaScript定义类或函数的几种方式小结
2011/01/09 Javascript
JavaScript高级程序设计阅读笔记(五) ECMAScript中的运算符(一)
2012/02/27 Javascript
JS 控件事件小结
2012/10/31 Javascript
javascript中拼接HTML字符串的最快、最好的方法
2014/06/07 Javascript
javascript实现锁定网页、密码解锁效果(类似系统屏幕保护效果)
2014/08/15 Javascript
JS图片定时翻滚效果实现方法
2016/06/21 Javascript
Bootstrap源码解读网格系统(3)
2016/12/22 Javascript
JavaScript中 this 指向问题深度解析
2017/02/21 Javascript
JavaScript 异步调用
2017/10/25 Javascript
Vue中 key keep-alive的实现原理
2018/09/18 Javascript
element vue validate验证名称重复 输入框与后台重复验证 特殊字符 字符长度 及注意事项小结【实例代码】
2018/11/20 Javascript
在antd Form表单中select设置初始值操作
2020/11/02 Javascript
pymssql ntext字段调用问题解决方法
2008/12/17 Python
Python实现遍历数据库并获取key的值
2015/05/17 Python
深入学习python的yield和generator
2016/03/10 Python
详解使用pymysql在python中对mysql的增删改查操作(综合)
2017/01/18 Python
Python和C/C++交互的几种方法总结
2017/05/11 Python
python 与服务器的共享文件夹交互方法
2018/12/27 Python
CSS3使用transition属性实现过渡效果
2018/04/18 HTML / CSS
您的网上新华书店:文轩网
2016/08/24 全球购物
墨西哥巴士车票在线购买:ClickBus
2018/03/27 全球购物
南京软件公司的.net程序员笔试题
2014/08/31 面试题
如何写好建议书
2014/03/13 职场文书
《苏珊的帽子》教学反思
2014/04/07 职场文书
微笑服务演讲稿
2014/05/13 职场文书
工地标语大全
2014/06/18 职场文书
开展党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
爱心募捐通知范文
2015/04/27 职场文书
python not运算符的实例用法
2021/06/30 Python
MYSQL如何查看进程和kill进程
2022/03/13 MySQL
讨论nginx location 顺序问题
2022/05/30 Servers