如何手动实现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 相关文章推荐
js最简单的拖拽效果实现代码
Sep 24 Javascript
javascript基于HTML5 canvas制作画箭头组件
Jun 25 Javascript
alert出数组中的随即值代码
Sep 25 Javascript
jquery获取节点名称
Apr 26 Javascript
AngularJS 实现JavaScript 动画效果详解
Sep 08 Javascript
微信小程序实现下拉菜单切换效果
Mar 30 Javascript
CKeditor4 字体颜色功能配置方法教程
Jun 26 Javascript
JS数组方法concat()用法实例分析
Jan 18 Javascript
Vue 如何使用props、emit实现自定义双向绑定的实现
Jun 05 Javascript
vue中实现点击变成全屏的多种方法
Sep 27 Javascript
微信小程序实现简单的select下拉框
Nov 23 Javascript
js Proxy的原理详解
May 25 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类的使用 实例代码讲解
2009/12/28 PHP
PHP 图片水印类代码
2012/08/27 PHP
用php实现百度网盘图片直链的代码分享
2012/11/01 PHP
PHP用continue跳过本次循环中剩余代码的注意点
2017/06/27 PHP
php使用ftp实现文件上传与下载功能
2017/07/21 PHP
使用Git实现Laravel项目的自动化部署
2019/11/24 PHP
JS对象与JSON格式数据相互转换
2012/02/20 Javascript
jQuery 快速结束当前正在执行的动画
2013/11/20 Javascript
jQuery实现统计复选框选中数量
2014/11/24 Javascript
AngularJS身份验证的方法
2016/02/17 Javascript
纯js代码制作的网页时钟特效【附实例】
2016/03/30 Javascript
AngularJS 获取ng-repeat动态生成的ng-model值实例详解
2016/11/29 Javascript
Bootstrap基本插件学习笔记之轮播幻灯片(23)
2016/12/08 Javascript
三种方式实现瀑布流布局
2017/02/10 Javascript
基于AngularJS的简单使用详解
2017/09/10 Javascript
每个 JavaScript 工程师都应懂的33个概念
2018/10/22 Javascript
JavaScript模板引擎原理与用法详解
2018/12/24 Javascript
vue+elementUI实现表格关键字筛选高亮
2020/10/26 Javascript
详细分析Node.js 多进程
2020/06/22 Javascript
python在windows下创建隐藏窗口子进程的方法
2015/06/04 Python
python多线程http压力测试脚本
2019/06/25 Python
Python爬虫实现使用beautifulSoup4爬取名言网功能案例
2019/09/15 Python
Python多重继承之菱形继承的实例详解
2020/02/12 Python
python numpy实现多次循环读取文件 等间隔过滤数据示例
2020/03/14 Python
python 递归调用返回None的问题及解决方法
2020/03/16 Python
最新PyCharm 2020.2.3永久激活码(亲测有效)
2020/11/26 Python
用python爬虫批量下载pdf的实现
2020/12/01 Python
.NET程序员的数据库面试题
2012/10/10 面试题
客户代表实习人员自我鉴定
2013/09/27 职场文书
酒店个人求职信范文
2014/01/25 职场文书
英语专业职业生涯规划范文
2014/03/05 职场文书
李敖北大演讲稿
2014/05/24 职场文书
北京奥运会主题口号
2014/06/13 职场文书
商铺门前三包责任书
2014/07/25 职场文书
护理医院见习报告
2014/11/03 职场文书
Mysql分库分表之后主键处理的几种方法
2022/02/15 MySQL