手写-call
call的作用
function myFn () {
console.log(this.name)
console.log(arguments)
}
const obj = {
name: 'zs'
}
myFn.call(obj,'aaa','bbb')
//call中第一个接收的参数为需要改变的this指向,后续参数为调用参数传参,call会自调用
//运行结果
zs
[Arguments] { '0': 'aa', '1': 'bb' }
实现思路
-
普通函数fn本质上也是一个对象,我们将mycall方法挂载到Function.prototype上
此时调用fn,发现它没有mycall方法,之后就会向原型链上去查找
找到了mycall方法,此时我们打印this,这个this指向的是fn,也就是谁调用它就指向谁
此时我们需要更改它的指向
将需要指向的obj传递进来 -
此时在obj下挂载一个函数,fn2
也就是obj.fn2指向当前的fn函数
就可以通过我们之前的this,
obj.fn2=this
此时
也就是相当于
obj={
name:'zs'
fn2:function(){
return fn(){console.log(this.name)}
}
}
我们在调用fn中的this.name,就会向它的上层中去寻找name,也就是达到了改变this指向的问题
- 下一步是考虑接受参数
将arguments进行slice切割,之后传递到fn中即可。这里可以回顾一下将arguments为数组转换为数组的几个常用方法- 使用扩展运算符
[...arguments]
Array.from()
Array.prototype.slice.apply(arguments)
- 使用for循环遍历,最后返回新数组
- 使用扩展运算符
代码实现
Function.prototype.mycall = function (context) {
// 短路运算符,如果有context,则就是context,否则就等于window
let args = [...arguments].slice(1)
context = context || window
context.fn = this
context.fn(...args)
delete context.fn
}
myFn.mycall(obj, 'aaa', 'bbb')
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类