call、apply 和 bind 均可显式指定函数执行时的 this 值:call 立即执行且参数逐个传入;apply 立即执行但参数以数组形式传入;bind 不执行,返回永久绑定 this 的新函数并支持柯里化。

在 JavaScript 中,this 的指向默认由函数**调用方式**决定,但 call、apply 和 bind 可以显式指定函数执行时的 this 值,也就是“运行上下文”。它们的核心区别在于:是否立即执行、参数传递形式、以及是否返回新函数。
call:立即执行,参数逐个传入
call 用于立即调用函数,并把第一个参数设为该次调用的 this 值,后续参数按顺序依次传入。
- 语法:
func.call(thisArg, arg1, arg2, ...) -
thisArg可以是任意值;若为null或undefined,非严格模式下指向全局对象(如window),严格模式下保持原值 - 适合已知参数个数、想立刻运行并控制
this的场景
示例:
const obj = { name: 'Alice' };
function greet(greeting, punctuation) {
console.log(`${greeting}, ${this.name}${punctuation}`);
}
greet.call(obj, 'Hello', '!'); // "Hello, Alice!"
apply:立即执行,参数以数组形式传入
apply 和 call 功能一致,都是立即调用,但第二个参数必须是**类数组或数组**,用于批量传参。
- 语法:
func.apply(thisArg, [arg1, arg2, ...]) - 常用于将一个数组“展开”作为函数参数,比如
Math.max(...arr)的兼容写法:Math.max.apply(null, arr) - 也适用于参数数量不确定、且已组织成数组的情况
示例:
const numbers = [3, 7, 1]; console.log(Math.max.apply(null, numbers)); // 7
bind:不执行,返回绑定好 this 的新函数
bind 不会立即调用函数,而是创建并返回一个**永久绑定指定 this 值**的新函数。该函数后续无论怎么调用,this 都不会变(除非用 new 调用)。
- 语法:
const boundFunc = func.bind(thisArg, arg1, arg2, ...) - 支持“预设参数”(柯里化):bind 后再调用时,前面 bind 的参数会自动前置
- 常用于事件监听、回调、需要长期固定上下文的场合(如
setTimeout中避免this丢失)
示例:
const user = { name: 'Bob' };
function introduce(age, city) {
console.log(`I'm ${this.name}, ${age} years old, from ${city}.`);
}
const introForBob = introduce.bind(user, 28);
introForBob('Beijing'); // "I'm Bob, 28 years old, from Beijing."
三者对比与使用建议
- 想立刻执行 + 参数少 → 优先用
call - 想立刻执行 + 参数是数组 → 用
apply - 不想立刻执行,要复用或传给其他函数(如
addEventListener、setTimeout)→ 用bind - ES6 箭头函数没有自己的
this,无法被这三种方法改变,它继承外层作用域的this - 注意:箭头函数、class 字段中的箭头方法、以及用
new调用的bind函数,其this行为有例外
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











