一、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转换后的数组。

  

最新文章

  1. Sql Server 2016 新功能——内置的 Temporal Tables
  2. MongoDB - basic
  3. 关于过拟合、局部最小值、以及Poor Generalization的思考
  4. java 数据类型
  5. 使用Dmitry Sklyarov的方法来破解一款流行的4G调制解调器
  6. a 中调用js的几种方法
  7. jstl if条件判断字符串代码
  8. yii2源码学习笔记(八)
  9. 如何从MVP模式进阶到Clean模式
  10. SVM公式推导笔记
  11. 学习Mathematica
  12. Django项目解决跨域问题
  13. maven安装和四大特性
  14. php5.4新功能Traits
  15. 【C++】C++中const与constexpr的比较
  16. Java-HttpURLConnection详细说明与实例
  17. LeetCode 429 N-ary Tree Level Order Traversal 解题报告
  18. Go指南 - 笔记
  19. Tomcat7.0无法启动解决方法[failed to start]
  20. TCP/IP 在 Windows 下的实现

热门文章

  1. Shell-->变量的数值计算
  2. 分享各大CMS采集资源站网址合集
  3. 以后可得记住了--Python笔试面试题小结
  4. 快应用list组件 scrollTo 方法的调用方式
  5. OpenCV学习笔记(一)、VS2015+OpenCV-4.1.1环境配置(Windows10)
  6. PHP小补充
  7. Java并发编程实战.笔记十一(非阻塞同步机制)
  8. 手把手教你用深度学习做物体检测(七):YOLOv3介绍
  9. P3084 [USACO13OPEN]照片Photo dp
  10. HDU4289Control 无向图拆点最大流