实现call函数polyfill触发错误,请求技术排查与解答
错误原因分析与修复方案
错误根源
你用箭头函数定义Function.prototype.mycall是核心问题:
- 箭头函数没有独立的
this绑定,它的this继承自声明时的外层作用域(这里是全局作用域)。当调用sample.mycall(obj)时,mycall内部的this指向全局对象(非严格模式)或undefined(严格模式),而非调用它的sample函数。因此typeof this !== "function"条件触发,抛出错误。
另外还有一个隐性问题:你定义的sample是箭头函数,箭头函数的this是固定的,即使通过call/apply也无法修改,所以就算mycall修复,sample内部的this.name和this.age依然会是undefined。
修复后的完整代码
obj = { name: "sai", age: 25 } // 将sample改为普通函数,让this可被call修改 sample = function() { console.log(`I am ${this.name} and is ${this.age} years old`) } // 用普通函数实现mycall,确保this指向调用它的函数 Function.prototype.mycall = function(obj, ...args) { if (typeof this !== "function") throw new Error("mycall can only be used on a function") // 处理obj为null/undefined的情况,默认绑定全局对象 const context = obj || globalThis // 临时挂载函数到目标对象 context.myFunc = this // 执行函数并保存结果 const result = context.myFunc(...args) // 清理临时属性 delete context.myFunc // 返回函数执行结果,对齐原生call的行为 return result } sample.mycall(obj)
关键修复点
- 替换箭头函数为普通函数:普通函数作为原型方法调用时,
this会自动指向调用该方法的函数实例(即sample),解决了this指向错误的问题。 - 修改sample为普通函数:只有普通函数的
this才能通过call/apply动态绑定,箭头函数的this无法被修改,这是JS的特性。 - 兼容obj为null/undefined的场景:原生
call在传入null或undefined时,会将this绑定到全局对象,这里增加了对应处理。 - 返回函数执行结果:原生
call会返回被调用函数的执行结果,修复后的代码也实现了这一点。
内容的提问来源于stack exchange,提问作者sai velagala
相关产品推荐
相关产品推荐

