一、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. Flink快速入门--安装与示例运行

    flink是一款开源的大数据流式处理框架,他可以同时批处理和流处理,具有容错性.高吞吐.低延迟等优势,本文简述flink在windows和linux中安装步骤,和示例程序的运行. 首先要想运行Flin ...

  2. SQL语言分类之DDL、DML、DCL、DQL

    SQL 语言共分为四大类: 数据控制语言 DCL 数据定义语言 DDL 数据操纵语言 DML 数据查询语言 DQL 一.数据控制语言 DCL 1.1 作用 用来设置或更改数据库用户或角色权限的语句,并 ...

  3. python 37 同步、异步调用

    目录 1. 阻塞与非阻塞 2. 同步与异步 2.1 异步调用 2.2 同步调用 2.3 异步调用回收的第一种方式 3. 异步调用+回调函数 3.1 requests模块 3.2 异步调用回收的第二种方 ...

  4. python 27 异常处理

    目录 异常处理 1. 错误分类 2. 异常 3. 异常处理 4. 异常处理的两种方法 5. try的结构 5.1 结构一:单分支结构 5.2 结构二:多分支结构 5.3 结构三:万能异常 5.4 结构 ...

  5. 解决ionic 中 $ionicHistory.goBack()无法返回

    这种解决方法目前只适合用了 <ion-side-menus>这一组件的<ion-view> 解决方法: 在<ion-view>下一级中包一个div,如下图: 搞了几 ...

  6. 读书分享全网学习资源大合集,推荐Python学习手册等三本书「01」

    0.前言 在此之前,我已经为准备学习python的小白同学们准备了轻量级但超无敌的python开发利器之visio studio code使用入门系列.详见 1.PYTHON开发利器之VS Code之 ...

  7. Linux--进程管理--06

    1.操作系统的基础 调用:kernel通过给应用程序提供system call的方式来提供硬件资源: 注意:应用程序也包括库文件 库文件是运行在ring0上的一段程序代码,不对客户直接提供应用 2.程 ...

  8. codeforces 816 E. Karen and Supermarket(树形dp)

    题目链接:http://codeforces.com/contest/816/problem/E 题意:有n件商品,每件有价格ci,优惠券di,对于i>=2,使用di的条件为:xi的优惠券需要被 ...

  9. CodeM 资格赛 B 可乐 思维

      分析: 我们假设购买一种可乐p瓶,我们可以得到期望:p*(m/n*a[i]+(n-m)/n*b[i]),由这个式子我们可以看出唯一的变量是i,所以可以遍历i找出式子的最大值 #include &l ...

  10. CF 987C Three displays DP或暴力 第十一题

    Three displays time limit per test 1 second memory limit per test 256 megabytes input standard input ...