一、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. .Net Core 三大Redis客户端对比和使用心得

    前言 稍微复杂一点的互联网项目,技术选型都可能会涉及Redis,.NetCore的生态越发完善,支持.NetCore的Redis客户端越来越多, 下面三款常见的Redis客户端,相信大家平时或多或少用 ...

  2. Spring学习之旅(十五)--SpringBoot

    在使用 Spring 的过程中,有时候会出现一些 ClassNotFoundException 异常,这是因为 JAR 依赖之间的版本不匹配所导致的.而 Spring Boot 就能避免绝大多数依赖版 ...

  3. Java基础之访问权限控制

    Java基础之访问权限控制 四种访问权限 Java中类与成员的访问权限共有四种,其中三种有访问权限修饰词:public,protected,private. Public:权限最大,允许所有类访问,但 ...

  4. 05_指针之New()函数的使用

    1.new函数是一个内置函数,表达式new(T)创建一个未命名的T类型变量,初始化为T类型的零值,并返回其地址(地址类型为*T)2.p:=new(int),q:=new(int)==>p!=q ...

  5. (八)分布式通信----主机Host

    上节中有谈到的是通信主机(TransportHost),本节中主机(ServiceHost)负责管理服务的生命周期. 项目中将两个主机拆分开,实现不同的功能: 通信主机:用于启动通信监听端口: 生命周 ...

  6. 一张图了解.Net Core和.NetFx和.Net Standard和Xamarin关系

    一张图了解 .Net Core和.Net Framework和.Net Standard和Xamarin关系 总结 .NET Standard是一项API规范,每一个特定的版本,都定义了必须实现的基类 ...

  7. C#开发BIMFACE系列7 服务端API之获取文件信息列表

    系列目录     [已更新最新开发文章,点击查看详细] 本文详细介绍如何获取BIMFACE平台中所有上传过的文件信息列表. 请求地址:GET https://file.bimface.com/file ...

  8. 关于Socket、TCP/IP、HTTP、FTP及网络编程

    来源:陶邦仁 链接:http://blog.jobbole.com/99694/ 既然是网络传输,涉及几个系统之间的交互,那么首先要考虑的是如何准确的定位到网络上的一台或几台主机,再者如何进行可靠高效 ...

  9. JavaScript label语句

    使用label 语句可以在代码中添加标签,以便将来使用. 以下是label 语句的语法: label: statement 下面是一个示例: start: for (var i=0; i < c ...

  10. [python]python子字符串的提取、字符串连接、字符串重复

    1. python使用索引运算符[]和切片运算符[:],来提取字符串. 第一个字符的索引是0,最有一个字符的索引是-1,切片运算符[x:y]表示提取从索引x到索引y-1的字符,不包含索引y. 示例: ...