call、apply、bind 的区别?如何手写实现?
三者对比
| 方法 | 参数 | 执行时机 | 返回值 |
|---|---|---|---|
call |
(thisArg, arg1, arg2, ...) |
立即执行 | 函数返回值 |
apply |
(thisArg, [argsArray]) |
立即执行 | 函数返回值 |
bind |
(thisArg, arg1, ...) |
返回新函数 | 新函数 |
手写 call
Function.prototype.myCall = function (ctx, ...args) {
ctx = ctx == null ? globalThis : Object(ctx)
const key = Symbol('fn')
ctx[key] = this
const result = ctx[key](...args)
delete ctx[key]
return result
}手写 apply
Function.prototype.myApply = function (ctx, args = []) {
ctx = ctx == null ? globalThis : Object(ctx)
const key = Symbol('fn')
ctx[key] = this
const result = ctx[key](...args)
delete ctx[key]
return result
}手写 bind
Function.prototype.myBind = function (ctx, ...outerArgs) {
const fn = this
return function (...innerArgs) {
// 支持 new 调用
if (new.target) {
return new fn(...outerArgs, ...innerArgs)
}
return fn.apply(ctx, [...outerArgs, ...innerArgs])
}
}核心原理
利用 对象.方法() 的隐式绑定规则,将函数作为对象的属性临时调用,使 this 指向该对象。用 Symbol 避免属性名冲突。