一、bind方法

让我们看一下MDN上对bind方法的解释

    bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用。

也就是说,bind()方法会:

  • 创建一个新的函数(这也是它和call、apply不同的点)
  • 创建的函数接收bind的第二个及以后的参数作为自己的参数

那bind创建的这个新函数还有其他什么特性吗?

    调用绑定函数时作为this参数传递给目标函数的值。 如果使用new运算符构造绑定函数,则忽略该值。

举个下面的例子:由bind创建的新函数bindFoo作为构造函数时,其创建的实例newBindFoo并不指向bindFoo绑定的obj,而是指向bindFoo。

var obj={
name:"Melody"
}
var name="huyang"
function foo(tel){
console.log(this.name)
console.log(tel)
}
var bindFoo=foo.bind(obj,"110") bindFoo()
//Melody
// var newbindFoo=new bindFoo();
//undefinde
//

二、现在可以尝试用call实现bind啦

先实现前两个特性,用call模拟bind绑定this,并且对arguments进行分割处理实现其余参数传递

Function.prototype.bind2 = function (context) {
var self = this;
var args=Array.prototype.slice.call(arguments,1)//模拟bind时的传参
return function () {
var bindArgs=Array.prototype.slice(arguments)//模拟执行bind的返回函数时的传参
self.apply(context,args.concat(bindArgs));//修改返回函数的this指向为context,并将bind时和执行bind的返回函数传入的参数concat后绑定给返回函数。
}
}

修改返回函数的作用域链,使其指向绑定函数,这样返回函数生成的实例就可以继承绑定函数的原型啦。

Function.prototype.bind2 = function (context) {
var self = this;
var args=Array.prototype.slice.call(arguments,1)//模拟bind时的传参
var foo=function() {
var bindArgs=Array.prototype.slice(arguments)//模拟执行bind的返回函数时的传参
self.apply(this instanceof self ? this : context, args.concat(bindArgs));
// 由于下方修改返回函数的prototype为绑定函数的prototype,当返回函数作为构造函数使用时,实例this instanceof self必定为真(instanceof判断的底层原理实际上就是根据原型链判断的)
// 当作为普通函数时,this 指向 window,self 指向绑定函数,此时结果为 false,当结果为 false 的时候,this 指向绑定的 context }
foo.prototype=this.prototype
return foo
}

需要注意的点:

    arguments只是具有length属性且可以通过index读取的类数组对象,并没有slice等数组方法,要想对arguments使用数组方法必须得将arguments转换为真正的数组。故,使用Array.prototype.slice.call(arguments),对Array原型链中的slice方法调用call(或apply),传入arguments作为其上下文,然后返回arguments转换后的数组。

  

用call或bind实现bind()的更多相关文章

  1. 山寨一个std::bind\boost::bind

    这里是最初始的版本,参考https://github.com/cplusplus-study/fork_stl/blob/master/include/bind.hpp 提供了最简洁的实现方式. 第一 ...

  2. 解决bind错误 bind: Address already in use

    关于bind错误的处理: bind: Address already in use 原因: 操作系统没有立即释放端口 解决一: 等待一段时间运行网络程序即可 解决二:通过setsockopt进行设置, ...

  3. JS核心系列:浅谈 call apply 与 bind

    在JavaScript 中,call.apply 和 bind 是 Function 对象自带的三个方法,这三个方法的主要作用是改变函数中的 this 指向,从而可以达到`接花移木`的效果.本文将对这 ...

  4. 【Win10】UAP/UWP/通用 开发之 x:Bind

    [Some information relates to pre-released product which may be substantially modified before it's co ...

  5. jQuery 中bind(),live(),delegate(),on() 区别(转)

    当我们试图绑定一些事件到DOM元素上的时候,我相信上面这4个方法是最常用的.而它们之间到底有什么不同呢?在什么场合下用什么方法是最有效的呢? 准备知识: 当我们在开始的时候,有些知识是必须具备的: D ...

  6. 转 jQuery 中bind(),live(),delegate(),on() 区别

    当我们试图绑定一些事件到DOM元素上的时候,我相信上面这4个方法是最常用的.而它们之间到底有什么不同呢?在什么场合下用什么方法是最有效的呢? 准备知识: 当我们在开始的时候,有些知识是必须具备的: D ...

  7. 深入浅出 妙用Javascript中apply、call、bind

    apply.call 在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向. Jav ...

  8. 【优雅代码】深入浅出 妙用Javascript中apply、call、bind

    这篇文章实在是很难下笔,因为网上相关文章不胜枚举. 巧合的是前些天看到阮老师的一篇文章的一句话: “对我来说,博客首先是一种知识管理工具,其次才是传播工具.我的技术文章,主要用来整理我还不懂的知识.我 ...

  9. 背水一战 Windows 10 (22) - 绑定: 通过 Binding 绑定对象, 通过 x:Bind 绑定对象, 通过 Binding 绑定集合, 通过 x:Bind 绑定集合

    [源码下载] 背水一战 Windows 10 (22) - 绑定: 通过 Binding 绑定对象, 通过 x:Bind 绑定对象, 通过 Binding 绑定集合, 通过 x:Bind 绑定集合 作 ...

随机推荐

  1. Docker学习总结(二)--Docker安装与启动

    注:笔者使用的环境为 CentOS 7.6,如果版本不一致可能会出现一些错误. 安装 Docker 1)将 yum 包更新到最新版本 sudo yum update 2) 安装需要的软件包 sudo ...

  2. Liunx学习总结(八)--服务

    什么是服务 服务是向外提供服务的进程,一般来说都会放在后台,既然要持续不断的提供外界随时发来的服务请求,服务进程就需要常驻在内存中,且不应该和终端有关,否则终端退出服务程序就退出了.另外,要能够接待外 ...

  3. HTML连载33-背景定位

    一.背景定位 同一个标签可以同时设置背景颜色和背景图片,如果颜色和图片同时存在,那么图片会覆盖颜色 1.在CSS中有一个叫做background-position:属性,就是专门用来控制背景图片的位置 ...

  4. macbook 安装redis流程及问题总结

    Mac安装redis流程和总结 一.redis安装流程: 1.进入redis官网-->点击download-->选择稳定版本(stable)-->点击Download即可. 2.将下 ...

  5. 漫话:如何给女朋友解释什么是"锟斤拷"?

    漫话:如何给女朋友解释什么是"锟斤拷"? ​ 周末女朋友出去逛街了,我自己一个人在家看综艺节目,突然,女朋友给我打来电话. 过了一会,女朋友回来了,她拿出手机,给我看了她在超市拍的 ...

  6. CentOS 7 下 JDK1.8+Maven+Nginx+MySql+Git+Redis环境安装

    CentOS 7 下 JDK1.8+Maven+Nginx+MySql+Git+Redis环境安装 安装目录准备 新建data目录,用来放下载的软件 mkdir -p /data 切换到该data目录 ...

  7. NLP(十七) 利用DNN对Email分类

    数据集 scikit-learn中20个新闻组,总邮件18846,训练集11314,测试集7532,类别20 from sklearn.datasets import fetch_20newsgrou ...

  8. CodeM 美团资格赛 思维 dfs

    链接:https://www.nowcoder.com/acm/contest/138/C来源:牛客网 世界杯就要开始啦!真真正正的战斗从淘汰赛开始,现在我们给出球队之间的胜负概率,来预测每支球队夺冠 ...

  9. 题解 UVA12716 GCD等于XOR GCD XOR

    规律题,打表找规律即可发现 a xor b >= a - b >= gcd(a, b), 如果 a xor b = gcd(a, b) = c 则 c = a - b 枚举倍数c和a判断b ...

  10. MAMP 访问时显示文件列表

    原文链接:他叫自己MR张 背景 MAMP是Mac下的一个PHP+Nginx+MySQL的集成环境,支持多站点,不同版本PHP. 今天有人请教MAMP如何显示文件列表的问题,这里记录一下. 知识补充 一 ...