本文正在参与掘金团队号上线活动,点击 查看大厂春招职位
一、call
call 接收多个参数,第一个参数为函数执行指定的上下文,剩余参数为函数执行实际入参。
1.代码实现
Function.prototype.mycall = function (ctx) {
if (typeof this !== "function") return
let args = [...arguments].slice(1)
let result
ctx = ctx || window
ctx.fn = this
result = ctx.fn(...args)
delete ctx.fn
return result
}
复制代码
2.实现逻辑
- 判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可 能出现使用 call 等方式调用的情况。
- 判断传入上下文对象是否存在,如果不存在,则设置为 window 。
- 处理传入的参数,截取第一个参数后的所有参数。
- 将函数作为上下文对象的一个属性。
- 使用上下文对象来调用这个方法,并保存返回结果。
- 删除刚才新增的属性。
- 返回结果。
二、apply
apply 接收两个参数,,第一个参数为函数执行指定的上下文,第二个参数是一个数组,数组中的每一项都会作为函数执行的实际参数。
1.代码实现
Function.prototype.myapply = function (ctx) {
if (typeof this !== "function") return
let args = arguments[1]
let result
ctx = ctx || window
ctx.fn = this
result = ctx.fn(args || null)
delete ctx.fn
return result
}
复制代码
2.实现逻辑
- 判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可 能出现使用 call 等方式调用的情况。
- 判断传入上下文对象是否存在,如果不存在,则设置为 window 。
- 将函数作为上下文对象的一个属性。
- 判断参数值是否传入
- 使用上下文对象来调用这个方法,并保存返回结果。
- 删除刚才新增的属性
- 返回结果
三、bind
bind 接收多个参数,第一个参数为函数执行指定的上下文,剩余参数为函数执行时的实际入参,与以上两个方法的区别是bind不会直接执行函数,而是将函数存为绑定好作用域的新函数存下来,供调用时使用。
1.代码实现
Function.prototype.mybind = function (ctx) {
if (typeof this !== "function") return
let args = [...arguments].slice(1)
let fn = this
return function Fn() {
return fn.apply(
this instanceof Fn ? this : context,
args.concat(...arguments)
)
}
}
复制代码
2.实现逻辑
- 判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可 能出现使用 call 等方式调用的情况。
- 保存当前函数的引用,获取其余传入参数值。
- 创建一个函数返回
- 函数内部使用 apply 来绑定函数调用,需要判断函数作为构造函数的 情况,这个时候需要传入当前函数的 this 给 apply 调用,其余情况都传 入指定的上下文对象。
END
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END