当前位置: 首页 > 后端技术 > Node.js

bind、call、apply的区别和实现原理

时间:2023-04-03 16:34:38 Node.js

1.简单说说bind、call、apply的区别  这三个都是用来改变函数体中this的方向的,但是bind、apply和call最大的区别就是:bind不会立即被调用,但会返回一个新的函数,称为绑定函数,其中this指向bind创建时传入的第一个参数,传入bind的第二个及以后的参数均以原函数的参数作为参数调用原始函数的原始函数。varobj={};functiontest(){console.log(this===obj);}test();//falsevartestObj=test.bind(obj);testObj();//true  apply和call都存在,改变一个函数的运行时上下文(即改变函数内部this的指针);apply和call的调用返回函数的执行结果;  如果使用apply或者call方法,那么this指向的是它们的第一个参数,apply的第二个参数是一个参数数组,call的第二个以后的参数都是数组中的元素,也就是说,必须全部列出;下面是MDN文档:bind语法:func.bind(thisArg[,arg1[,arg2[,...]]])thisArg当绑定函数被调用时,这个参数将作为this指针,当原始函数被调用时运行。使用new运算符调用绑定函数时,该参数无效。arg1,arg2,...当调用绑定函数时,这些参数将在实际参数之前传递给绑定方法。调用语法:fun.call(thisArg,arg1,arg2,...)thisArg::fun函数运行时指定的this值。需要注意的是,指定的this值不一定是函数执行时真正的this值。如果函数处于非严格模式,指定为null和undefined的this值将自动指向全局对象(在浏览器中为window对象),而原始值(number、string、boolean)的this值)将指向原始值的自动包装对象。arg1,arg2,...指定参数列表。apply语法:fun.apply(thisArg,[argsArray])thisArg:fun函数运行时指定的this值。需要注意的是,指定的this值不一定是函数执行时真正的this值。如果函数是非严格模式,当指定为null或undefined时,会自动指向全局对象(浏览器中的window对象),而this的值是一个原始值(数字,字符串),布尔值)将指向原始值的自动包装对象。argsArray:一个数组或类数组对象,其元素将作为单独的参数传递给fun函数。如果这个参数的值为null或undefined,则表示不需要传入任何参数。从ECMAScript5开始可以使用类数组对象。区别总结:当我们使用一个函数,需要改变this的方向时,会用到call、apply、bind。如果你传递的参数不多,可以使用fn.call(thisObj,arg1,arg2...)如果你传递的参数很多,可以用一个数组来组织参数,调用fn。apply(thisObj,[arg1,arg2...])如果你想生成一个新的函数并且长时间绑定一个函数到一个对象,那么你可以使用constnewFn=fn.bind(thisObj);newFn(arg1,arg2...)2,bind,call,applytoimplementmyBind:Function.prototype.myBind=function(){var_this=this;varcontext=[].shift.call(arguments);//保存需要绑定的this上下文varargs=[].slice.call(arguments);//其余参数转为数组console.log(_this,context,args);returnfunction(){return_this.apply(context,[].concat.call(args,[].slice.call(arguments)));}};myCall:/***每个函数都可以调用call方法,改变当前函数执行的this关键字,支持参数的传递*/Function.prototype.myCall=function(context){//第一个参数是this指向调用call方法的函数中的varcontext=context||全球的;//将this赋值给context的fn属性context.fn=this;//这里的this指的是调用myCall的函数vararr=[];对于(vari=0,len=arguments.length;i