之前对bind方法的了解一直很模糊,今天重新认识了下这个方法,记一波笔记。如果有描述不恰当的地方,还请各位大神指点~
今天看了把犀牛书,书上对bind的一句描述是:这个方法的主要作用就是将函数绑定到某个对象。
举个例子:
var fn1 = function (y) {return this.x + y;}
var obj1 = {x:1}
var fn2 = fn1.bind(obj1);
此时,函数fn1被绑定到对象obj1上。绑定后,在函数fn1中可以调用obj1中的属性(这种现象叫‘柯里化’)。现在可以通过调用fn2(x)来调用obj1.fn1(x),即:
fn(2); //输出3
倘若此时,我把函数fn1的入参也绑定成一个值,即把函数fn2改写为如下形式:
fn2 = fn1.bind(obj1,2);
此时再调用fn2可以不传入参数,可以理解为给函数fn1的入参设置了一个默认值为2,即:
fn2(); //输出3
当然,有的小伙伴会说,那我就是要给fn2一个参数咋办?会不会覆盖掉之前给函数fn1入参绑定的那个值呢?答案是:不会!
在给fn1的入参绑定一个值后,不论之后给函数fn2传入什么样的参数,或者是多少个参数,都不会对绑定的值产生影响,依旧会将绑定的值作为fn1的入参,即:
fn2(1);//输出3
fn2(1,2,3,4,5,6,7,'abcdefg');//输出3
那如果fn1具备多个参数呢?我们来改写上述例子如下:
var fn1 = function (y,z) {return this.x + y + z;}
var obj1 = {x:1}
var fn2 = fn1.bind(obj1);
在未给函数fn1的入参绑定值的时候,此时调用fn2需要传入两个参数:
fn2(2,3);//输出6
如果给fn1的第一个入参绑定了值,调用fn2的时候只需要传入一个参数,即:
fn2 = fn1.bind(obj1,2);
fn2(3);//输出6
那又有小伙伴儿会问了,要是这个时候我给fn2传入两个参数呢?既然函数fn1的第一个参数被绑定成2,不能被覆盖,那是不是fn2的第二个参数会被作为fn1的第二个参数被传入呢?
答案是:不会!
在这种情况下,函数fn2的第一个参数将被作为函数fn1的第二个参数传入,不论fn2后面还有多少参数,都不会起作用!即:
fn2(1,2,3,4,5,6,7);//输出4
利用bind的这种特性,我可以给某个函数的入参设置默认值,例如:
var fn3 = function(x,y) {return x + y;}
var fn4 = fn3.bind(null, 3);//x的值此时绑定为3
fn4(3); //输出6
当然,我也可以将某个函数绑定到某个构造函数的实例上,借此调用到这个构造函数里的属性:
var fn5 = function () {
this.a = 1;
this.b = 2;
}
fn5.prototype.sum = function (x, y) {
return x + y;
}
var newObj = new fn5();
var fn6 = function (x, y) {
return this.sum(x ,y) + this.a + this.b;
}
var fn7 = fn6.bind(newObj, 1, 2);
fn7(); // 输出6
以上就是我对bind函数的理解,如有不对之处,还请各位指正~