标准答案
- call 接收 thisArg 和参数列表,apply 接收 thisArg 和参数数组。
- 实现 call/apply 可以把函数临时挂到 thisArg 上调用,再删除临时属性。
- thisArg 为 null 或 undefined 时,非严格模式下通常指向全局对象。
- bind 返回新函数,不会立即执行,并支持预置参数。
- bind 返回的函数被 new 调用时,this 应该指向新实例,而不是绑定时传入的对象。
题目解析
这道题考的是 this 绑定规则。call/apply 改变的是本次调用的 this,bind 改变的是未来调用的 this,并且可以提前固定一部分参数。
临时属性调用法能解释为什么 this 会指向目标对象:函数作为对象方法被调用时,方法内部 this 指向这个对象。为了避免属性名冲突,应该使用 Symbol 作为临时 key。
bind 的 new 规则是常见进阶点。绑定函数作为构造函数使用时,绑定的 thisArg 会被忽略,但预置参数仍然生效。
代码示例
下面是核心行为版本,重点展示 this 绑定、参数传递和 bind 的构造调用边界。
JavaScript
function myCall(fn, thisArg, ...args) {
const context = thisArg == null ? globalThis : Object(thisArg)
const key = Symbol('fn')
context[key] = fn
const result = context[key](...args)
delete context[key]
return result
}
function myApply(fn, thisArg, args = []) {
return myCall(fn, thisArg, ...args)
}
function myBind(fn, thisArg, ...presetArgs) {
function bound(...args) {
const isNew = this instanceof bound
const context = isNew ? this : thisArg
return fn.apply(context, [...presetArgs, ...args])
}
bound.prototype = Object.create(fn.prototype)
return bound
}常见误区
- bind 写成直接执行函数,忘记它应该返回新函数。
- call/apply 临时属性名使用普通字符串,可能覆盖目标对象已有属性。
- 没有处理 bind 返回函数被 new 调用时的 this 规则。