摘要:方法简介在中,函数中的指向往往在调用时才可确定,而提供了方法让我们得以显示绑定函数的指向。它们的第一个参数是一个对象,它们会把这个对象绑定到调用他们的函数内的。
call/apply/bind方法简介
在JavaScript中,函数中this的指向往往在调用时才可确定,而JavaScript提供了call/apply/bind方法让我们得以显示绑定函数的this指向。
它们的第一个参数是一个对象,它们会把这个对象绑定到调用他们的函数内的this。因为你可以直接指定 this 的绑定对象,因此我们称之为显式绑定。
//用例 var a = { q: 1 }; var b = { q: 2 }; var c = { q: 3 }; function cs(s) { console.log(this.q) } cs.bind(a)();//1 cs.call(b);//2 cs.apply(c);//3tips
var s = new fn.myBind({ a: 2333 })();//报错!!,运算优先级:属性访问>带参new>函数调用>无参new var s = new (fn.myBind({ a: 2333 }))();//正确姿势自定义Call方法实现
参数从arguments[1]开始,func.myCall(obj:Object[,agr1:any[,agr2:any[...]]])
if (!Function.prototype.myCall) { Function.prototype.myCall = function (targetThis) { //targetThis默认为windows(严格模式不允许) targetThis = targetThis || window; //利用对象调用指定this targetThis.fn = this; //收集参数 var agrs = []; //因为arguments[0]===targetThis,故从下标1开始 for (var ge = 1, len = arguments.length; ge < len; ge++) { agrs.push("arguments[" + ge + "]"); } //利用eval展开参数 并执行函数 var result = eval("targetThis.fn(" + agrs + ")"); //删除附加对象的属性以消除副作用 delete targetThis.fn; //返回结果 return result; } }自定义apply方法实现
参数放在数组里func.call(obj:Object[,agr:Array])
if (!Function.prototype.myApply) { Function.prototype.myApply = function (targetThis, arrAgrs) { //targetThis默认为windows(严格模式不允许) targetThis = targetThis || window; //利用对象调用指定this targetThis.fn = this; var agrs = []; //收集参数数组 for (var ge = 0, len = arrAgrs.length; ge < len; ge++) { agrs.push("arrAgrs[" + ge + "]"); } //利用eval展开参数 并执行函数 var result = eval(" targetThis.fn(" + agrs + ")"); //删除附加对象的属性以消除副作用 delete targetThis.fn; //返回结果 return result; } }自定义bind方法实现
参数从arguments[1]开始,func.myCall(obj:Object[,agr1:any[,agr2:any[...]]])
//考虑参数合并以及new优先级和原型继承 if (!Function.prototype.myBind) { Function.prototype.myBind = function (targetThis) { //若非函数对象来调用本方法,报异常 if (typeof this !== "function") { throw new TypeError( "Function.prototype.bind error" ); } //收集参数 var bindArgs = Array.prototype.slice.call(arguments, 1), originFunction = this,//保存原始this(原始函数) fnProto = function () { },//利用空函数间接链接prototype以应对new时的原型继承 fnBounding = function () { //考核new操作this绑定优先 return originFunction.apply( ( this instanceof fnProto ? this : targetThis ), bindArgs.concat( Array.prototype.slice.call(arguments) ) ) }; fnProto.prototype = this.prototype;//链接原型 //new一个fnProto以实现简洁继承原型,防止对fnBounding.prototype的操作污染originFunction原型prototype fnBounding.prototype = new fnProto(); return fnBounding; }; }软绑定
bind之后可以再bind或call/apply
if (!Function.prototype.softBind) { Function.prototype.softBind = function (obj) { var fn = this; // 捕获所有 bindArgs 参数 var bindArgs = [].slice.call(arguments, 1); var fnBounding = function () { return fn.apply( (!this || this === (window || global)) ? obj : this, curried.concat.apply(bindArgs , arguments) ); }; fnBounding .prototype = Object.create(fn.prototype);//链接原型 return fnBounding ; }; }
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/106429.html
摘要:来自朋友去某信用卡管家的做的一道面试题,用原生模拟的方法,不准用和方法。他们的用途相同,都是在特定的作用域中调用函数。不同之处在于,方法传递给调用函数的参数是逐个列出的,而则是要写在数组中。 本文首发我的个人博客:前端小密圈,评论交流送1024邀请码,嘿嘿嘿?。 来自朋友去某信用卡管家的做的一道面试题,用原生JavaScript模拟ES5的bind方法,不准用call和bind方法。 ...
摘要:来自朋友去某信用卡管家的做的一道面试题,用原生模拟的方法,不准用和方法。他们的用途相同,都是在特定的作用域中调用函数。不同之处在于,方法传递给调用函数的参数是逐个列出的,而则是要写在数组中。 本文首发我的个人博客:前端小密圈,评论交流送1024邀请码,嘿嘿嘿?。 来自朋友去某信用卡管家的做的一道面试题,用原生JavaScript模拟ES5的bind方法,不准用call和bind方法。 ...
摘要:不能应用下的等方法。首先我们可以通过给目标函数指定作用域来简单实现方法保存,即调用方法的目标函数考虑到函数柯里化的情况,我们可以构建一个更加健壮的这次的方法可以绑定对象,也支持在绑定的时候传参。原因是,在中,多次是无效的。 bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。 apply、call 在 javascript 中,call 和 apply 都是...
摘要:首先我们可以通过给目标函数指定作用域来简单实现方法保存,即调用方法的目标函数考虑到函数柯里化的情况,我们可以构建一个更加健壮的这次的方法可以绑定对象,也支持在绑定的时候传参。原因是,在中,多次是无效的。而则会立即执行函数。 bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。 apply、call 在 javascript 中,call 和 apply 都是...
阅读 3237·2021-10-11 11:08
阅读 4379·2021-09-22 15:54
阅读 869·2019-08-30 15:56
阅读 829·2019-08-30 15:55
阅读 3498·2019-08-30 15:52
阅读 1312·2019-08-30 15:43
阅读 1906·2019-08-30 11:14
阅读 2464·2019-08-29 16:11