手写call&apply
参考
来源:https://www.bilibili.com/video/BV1sN411974w?p=2
细讲:https://www.jianshu.com/p/b5d39d2046ae
1. call()
call()
可以被所有的函数继承,所以call()
应该被定义在Function.prototype
上call()
将this
绑定到第一个入参指定的对象上,并根据传入的参数执行函数
Function.prototype.myCall = function(context, ...args){
// 不传第一个参数默认为windows
context = context || window
//普通函数的this指向调用者, 故this就是要改造的那个函数
//将函数挂载到目标对象上
context.func = this
//执行函数,并保存返回值
let res = context.func(...args)
//删除之前挂载在目标对象上的函数,还原目标对象
delete context.func
//return返回值
return res
}
2. apply()
apply()
与call()
唯一的区别就是前者需要将目标函数的入参逐个传入,后者的入参则以数组形式被传入。
Function.prototype.myApply = function(context, args){
context = context || window
context.func = this
let res = context.func(...args)
delete context.func
return res
}
3. bind()
bind()
入参方式是逐个传入, 但是bind()
返回值是一个函数
Function.prototype.myBind = function(context, ...args){
let _this = this
return function Fn(){
//因为返回值是一个函数,需要判断 new Fn() 的情况
//new 会让 this 指向这个新的对象,所以直接判断 Fn 是否在 this 的原型链上
if(this instanceof Fn){
return new _this(...args, ...arguments)
}
//调用 call 改变 this 指向
return _this.call(context, ...args, ...arguments)
}
}
本文来自博客园,作者:沧浪浊兮,转载请注明原文链接:https://www.cnblogs.com/shixiu/p/15993036.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步