理解bind函数

前言:之前一直不懂这个函数是干嘛的,最近慢慢有点懂了,说一说自己的理解~

本文按以下3个方面来谈谈bind函数

1)对bind函数的理解;

2)如何使用bind函数

3)自定义bind函数

https://msdn.microsoft.com/zh-cn/library/ff841995中有bind函数较详细的说明)

bind函数的理解

语法:

function.bind(thisArg[,arg1[,arg2[,argN]]])

首先不看传的参数,bind函数实现的功能就是将function绑定在thisArg环境上,使其可以在thisArg上调用function。听起来这和apply/call的作用好像一样,那到底是不是一样呢?

var a={x:1};
function foo(){
  return this.x;
}
console.log(foo.call(a));//1
console.log(foo.bind(a));//function foo(){return this.x;}

观察以上代码发现,call函数实现了在a对象上调用foo函数,但bind函数却返回了foo的主体。那这不是没起任何作用?

var a={x:1};
function foo(){
  return this.x;
}
var foo_bind = foo.bind(a);
console.log(foo);//function foo(){return this.x;}
console.log(foo_bind);//function foo(){return this.x;}
console.log(foo());//undefined
console.log(foo_bind());//1

通过以上代码可以发现,虽然通过bind绑定后返回的是foo函数主体,但是有差别的:通过bind绑定后返回的函数运行时已经是在a的环境中运行了(而单独运行foo是在window中,所以this.x返回undefined)。

综上可以总结为:bind函数实现与call/apply相似的功能:将给定函数绑定到特定的this环境中;但是bind函数绑定不是立刻执行,只是实现绑定,等到需要执行的时候再执行,此时才完成了和call/apply一样的功能。

那bind函数的这个作用又什么用呢?它一般用在回调函数和事件处理程序中(也就是异步编程中),举个例子

//bind方法
btn.onclick = foo.bind(a);
//匿名函数方法
btn.onclick = function(){
  foo.call(a);
}

以上两种方法实现相同的功能,再举个例子

//bind方法
setTimeout(foo.bind(a), 1000);
//匿名函数方法
setTimeout(function() { foo.call(a); }, 1000);

通过以上两个例子可以很清楚的看出,call函数相当于把绑定和执行一次性完成了(匿名函数达到了将其分开的作用),bind函数就是将绑定与执行分开了。

如何使用bind函数

上一部分其实已经讲了怎么使用,这一部分主要是将带参数是怎么使用。

规则:绑定函数将bind中指定的参数作为优先参数,在调用绑定函数时指定的参数作为辅助参数。啥意思?

var a={};
function foo(a,b,c){
  alert( a+b+c);
}
var foo_bind = foo.bind(a,"A","B")
foo_bind("X","Y","Z");//"ABX"
var foo_bind2 = foo.bind(a,"A","B","C")
foo_bind2("X","Y","Z");//"ABC"

观察以上代码,发现“A”,"B”作为优先参数转给了函数foo,而调用时传入的"X","Y","Z"要接在"A","B"后面(如果还需要就传,不需要了就不传了)

自定义bind函数

通过第一部分的讲解,其实自定义bind就很简单了。

首先,先不考虑传参数,写出简单的自定义bind

var a={x:1};
function foo(a,b,c){
 alert (a+b+c+this.x);
}
function bind(fn,context){
  return function(){
    return fn.apply(context,arguments); } } var foo_bind=bind(foo,a); foo_bind("A","B","C");//"ABC1"

可以看出,其实就是用一个闭包把apply/call函数包起来了(即第一部分中讲到的),这里用apply是为了方便用arguments传参。注意,这里的arguments是指调用时的参数,而不是bind函数的。

接下来考虑给bind函数传参数。

var a={x:1};
function foo(a,b,c){
 alert (a+b+c+this.x);
}
function bind(fn,context){
  //从第3个参数开始取
  var args1 = Array.prototype.slice.call(arguments,2);
  return function(){ //将bind函数的参数args1与调用时的参数arguments按先后顺序排列 var args2= args1.concat(Array.prototype.slice.call(arguments)); return fn.apply(context,args2); } } var foo_bind=bind(foo,a,"a"); foo_bind("A","B","C");//"aAB1"

到这里,就算都讲完了。这是我自己的理解,希望可以帮到你~

参考资料:

1)https://msdn.microsoft.com/zh-cn/library/ff841995

2)《JavaScript高级程序设计(第3版)》第602-604页。

转载于:https://www.cnblogs.com/youhong/p/6781008.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值