Appearance
2754. 将函数绑定到上下文
ts
type Fn = (...args) => any
interface Function {
bindPolyfill(obj: Record<any, any>): Fn
}
Function.prototype.bindPolyfill = function (
this: Fn,
obj: Record<any, any>,
...args: any[]
): Fn {
const originalFn = this
return function (...innerArgs: any[]) {
return originalFn.apply(obj, [...args, ...innerArgs])
}
}bind 的三个能力
原生 bind 做了三件事:
- 固定 this:无论返回的函数在什么上下文中调用,this 都指向绑定的对象
- 预绑定参数:第一次传入的 args 排在前面,后续调用时传入的接在后面
- 返回新函数:不执行原函数
这个 polyfill 实现了全部三个。
闭包保存了什么
originalFn 保存原函数引用,obj 保存目标 this,args 保存预绑定参数。这些都是通过闭包捕获的。返回的新函数每次调用时,把预绑定参数和实际参数拼接后通过 apply 传给原函数。
注意 this: Fn 是 TypeScript 的 this 参数声明——它不占用实际参数位,只用于类型检查,表示 bindPolyfill 期望在函数对象上以方法形式调用。
边界
bindPolyfill返回的函数如果用new调用,行为会不同——原生bind在new调用时 this 绑定失效。这个 polyfill 没有处理这个场景- 多次 bind 只有第一次生效(
bind不是链式的),返回函数的length会被重新计算
