理解并手写 call() 函数
手写自己的call,我们要先通过call的使用,了解都需要完成些什么功能?
我们把手写的函数起名为myCall,obj作为形参承载传过来的第一个参数(即绑定的对象)。
Function.prototype.myCall = function(obj){}
call的调用对this的指向进行了改变,而this是函数,这是前提(对this进行判断)。
Funtion.prototype.myCall = function(obj){ // 判断调用对象是否为函数 if(typeof this !== 'function'){ console.error('type error') } }
同理应当判断是否传入了参数,如果没有传入参数,则绑定的对象设置为window。
Funtion.prototype.myCall = function(obj){ if(typeof this !== 'function'){ console.error('type error') } // 判断绑定的对象 obj = obj || window; }
要调用这个this方法,我们可以先将其作为对象的属性方法,然后调用。
Function.prototype.myCall = function(obj){ if(typeof this !== 'function'){ console.error('type error!'); } obj = obj || window; // 添加属性方法,并调用 obj.fn = this; obj.fn(); }
call调用完后,拥有使用完方法后的返回值,所以肯定要将方法的执行结果保存并返回。
Function.prototype.mycall = function(obj){ if(typeof this !== 'function'){ console.error('type error!') } obj = obj || window; obj.fn = this; // 将执行结果保存,并返回 let result = obj.fn(); return result; }
在原对象中,并没有obj.fn属性,所以我们要将其进行删除。
Function.prototype.mycall = function(obj){ if(typeof this !== 'function'){ console.error('type error!') } obj = obj || window; obj.fn = this; let result = obj.fn(); // 删除context.fn属性 delete obj.fn; return result; }
最后考虑下方法中使用的参数(从传递过来的第二个参数开始),通过slice()进行切割,并拼凑为数组。
Function.prototype.mycall = function(obj){ if(typeof this !== 'function'){ console.error('type error!') } // 获取正确参数 let args = [...arguments].slice(1) obj = obj || window; obj.fn = this; let result = obj.fn(...args); delete obj.fn; return result; }
最后通过一个例子,来验证是否达到call()的功能要求。
Function.prototype.myCall = function(obj) { if (typeof this !== 'function') { console.error('type error!'); } obj = obj || window; let args = [...arguments].slice(1); obj.fn = this; let result = obj.fn(...args) delete obj.fn; return result; } let dog = { name: '狗', eat(food1, food2) { console.log(this.name + '爱吃' + food1 + food2); } } let cat = { name: '猫', } dog.eat.call(cat, '鱼', '肉'); // 猫爱吃鱼肉 dog.eat.myCall(cat, '鱼', '肉'); // 猫爱吃鱼肉
另外两篇:'对apply()函数的分析' 和 '对bind()函数的分析' 。
本文来自博客园,作者:辉太狼`,转载请注明原文链接:https://www.cnblogs.com/HuiTaiLang1216/p/15974486.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类