「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战」。
call、apply、bind 区别
-
共同点:改变
this
指向 -
不同点:
apply
的传递的参数是数组call
和bind
都是一个个传递bind
返回的是一个函数 而call
和apply
返回的是函数的调用
标题 | call | apply | bind |
---|---|---|---|
共同点 | 改变this 指向 | 改变this 指向 | 改变this 指向 |
参数传递 | 按个传递 | 传递数组 | 按个传递 |
返回值 | 函数的调用 | 函数的调用 | 函数 |
实现 call & apply
apply
和call
的区别只是参数传递方式的不同,所以放在一起实现,会比较好理解
思路
- 创建一个临时空对象
- 生成一个唯一的
key
- 将
ctx[key]
赋值成调用函数 - 执行调用函数,并保存结果
- 删除执行函数
- 返回函数调用的结果
const core = (ctx, args, _this) => {
const obj = {}
// 生成一个唯一key
const key = Symbol()
// 将调用函数赋值
ctx[key] = _this
// 执行调用函数
const res = ctx[key](...args)
// 删除调用函数
delete ctx[key]
// 返回调用函数的结果
return res
}
// apply
Function.prototype.applyFn = function(ctx, args) {
return core(ctx, args, this)
}
// call
Function.prototype.callFn = function(ctx, ...args) {
return core(ctx, args, this)
}
实现 bind
Function.prototype.bindFn = function() {
const fn = this
// 获取要指向的对象
const _this = arguments[0]
// 获取调用时的参数
const tempArgs = [].slice.call(arguments, 1)
// 创建一个函数
const F = function(){}
F.prototype = fn.prototype
// 返回一个函数
const retFn = function () {
// 获取返回后的函数,传入的参数
const retArgs = [].slice.call(arguments)
// 执行原本的函数, 如果返回的函数被 new 就要忽略绑定的
return fn.apply(fn instanceof F ? fn : _this, tempArgs.concat(retArgs))
}
retFn = new F()
return refFn
}