大家好,我是前端西瓜哥。今天我们使用JS来实现内置的bind方法。bind的用法在实现之前,我们先学习一下Function.prototype.bind的用法。function.bind(thisArg[,arg1[,arg2[,...]]])bind是一个特定于函数的方法,它可以创建一个绑定到this的新函数。接受的参数如下。第一个参数thisArg:用于修改this的指向,修改后this不可更改。arg1,arg2,...:其余为可选参数项,在调用bind返回的新函数时,会作为函数的前几个参数被调用。this的指向问题我们在开发的时候,有时候会遇到JS中缺少this指向的问题。让我们看下面的例子。constperson={nickname:'西瓜',eatWatermelon(){console.log(this.nickname+'吃西瓜');}};person.eatWatermelon();上面代码中,调用person.eatWatermelon时,this指向person,输入结果为前端吃西瓜的西瓜哥。让我们再次执行以下代码。consteatWatermelon=person.eatWatermelon;吃西瓜();输入的结果很不可思议,是:undefined吃西瓜。这是因为this的点变成了eatWatermelon()执行范围的this。在浏览器脚本标签的最外层,是全局对象window(在严格模式下,全局对象this会变成undefined)。所以eatWatermelon()执行中的this.nickname就相当于window.nickname,因为我们还没有赋值,所以是undefined。有时候我们不想让这个丢失,怎么办?这个时候我们会用到一个bind方法,可以永久的改变this的方向,不能再次改变。consteatWatermelon=person.eatWatermelon.bind(person);吃西瓜();这样eatWatermelon函数的this就会一直指向person,这样就可以输出我们期望的前端西瓜哥吃西瓜了。因此,对于一个函数来说,它的this点是在执行时确定的:如果函数是bind返回的,那么this总是指向执行bind绑定的thisArg值。如果函数前面有一个对象,那么this指向这个对象。如果函数前没有对象,那么this指向当前作用域(可能是函数作用域,也可能是全局作用域)。另一种控制this指向的方法是使用箭头函数,它特别适合在一个函数中调用另一个函数,这里由于篇幅原因不再赘述。累加参数bind不仅常用来绑定this,还有一个比较少用的功能:预置函数参数。functionadd(a,b,c){returna+b+c;}constaddSix=add.bind(null,6);constaddSixThenAddFour=addSix.bind(null,4);addSixThenAddFour(5)//15addSixThenAddFour(7)//17实现一个绑定下面进入正题,实现一个绑定。Function.prototype.myBind=function(thisArg,...prefixArgs){constfn=this;returnfunction(...args){returnfn.call(thisArg,...prefixArgs,...args);}}重点是利用闭包。让返回的新函数可以访问三个私有属性:fn(原始函数)。thisArg(需要绑定不变的this点)。prefixArgs属性。当我们调用这个新函数时,会执行fn函数,使用call方法指定this为thisArg,然后依次填入预填的多个参数和新函数接收到的参数。最后不要忘记在调用后返回值。因为新函数是对原函数的封装,返回值也必须和原函数一样。最后bind方法的实现并不复杂,更重要的是你必须先掌握bind的用法。就像做业务需求一样,如果不明确需求,很容易产生bug,然后需要对闭包,如何保??存私有变量,如何写封装函数有一定的了解(记得回原函数的返回值)。
