【js】Function.prototype.apply与Function.prototype.apply.call
这是一个非常经典的 JavaScript 底层机制问题,涉及到 Function.prototype
上的方法调用机制。
1. Function.prototype.apply
是什么?
这是 JavaScript 中所有函数对象继承的方法之一,用于 以指定 this 和参数数组调用函数。
function foo(a, b) {console.log(this.x, a, b);
}foo.apply({x: 42}, [1, 2]); // 输出: 42 1 2
2. Function.prototype.apply.call
是什么?
这是 先拿到 apply
方法,再用 call
调用它。结构如下:
Function.prototype.apply.call(fn, thisArg, argsArray)
等价于:
fn.apply(thisArg, argsArray)
3. 区别总结
表达式 | 等价于 | 解释 |
---|---|---|
Function.prototype.apply(fn, thisArg, [args]) | ❌ 错误 | 错误用法,apply 不是静态方法 |
Function.prototype.apply.call(fn, thisArg, [args]) | fn.apply(thisArg, [args]) | ✅ 正确,借用 apply |
Function.prototype.call.apply(fn, [thisArg, arg1, arg2]) | fn.call(thisArg, arg1, arg2) | ✅ 同理,借用 call |
4. call
在这里的作用是什么?
Function.prototype.apply.call(fn, ...)
这个 .call
的作用是:
改变
apply
方法的调用者,使其作用于任意函数对象fn
,而不是默认的Function.prototype
。
换句话说:
apply
是函数的方法,必须绑定在某个函数上调用。- 使用
.call
是为了告诉引擎:“我现在要用apply
,但让它作用在fn
上。”
5. 例子
function greet(name) {console.log(`Hello ${name}, I'm ${this.name}`);
}const person = { name: 'Alice' };// 正常写法
greet.apply(person, ['Bob']);
// Hello Bob, I'm Alice// 使用 .call 借用 apply
Function.prototype.apply.call(greet, person, ['Bob']); // 同上// 使用 .apply 借用 apply
Function.prototype.apply.apply(greet, [person, ['Bob']]); // 同上// 使用 .bind 借用 apply
Function.prototype.apply.bind(greet)(person_apply, ['Bob']); // 同上// 使用 .call 借用 bind
Function.prototype.bind.call(greet, person_apply, 'Bob')(); // 同上
参考:
KIMI AI