bind,apply,call
方法 | 作用 | 是否立即执行函数 |
---|---|---|
call | 指定函数内部的 | ✅ 立即执行 |
apply | 指定函数内部的 | ✅ 立即执行 |
bind | 指定函数内部的 | ❌ 不立即执行,返回新函数 |
✅ 二、共同点
三者都用于 显式绑定函数执行时的 this 值,解决 this 指向不确定或不正确的问题。
✅ 三、区别(核心区别)
方法 | 调用时机 | 参数传递方式 | 是否立即执行 | 主要用途 |
---|---|---|---|---|
call | 立即调用函数 | 参数逐个传递,如 | ✅ 立即执行 | 立即调用,且明确 this 和参数 |
apply | 立即调用函数 | 参数以 数组(或类数组) 传递,如 | ✅ 立即执行 | 立即调用,且明确 this 和参数(适合参数数量不确定) |
bind | 不立即调用,返回一个绑定了 this 的新函数 | 参数逐个传递(可后续再传) | ❌ 不立即执行 | 延迟调用,常用于事件回调、定时器等需要固定 this 的场景 |
✅ 四、分别什么时候用?(具体使用场景)
✅ 1. 什么时候用 call?
✅ 场景:你想要立即调用一个函数,并明确指定它的 this 值,且参数是逐个传递的
✅ 适用情况举例:
调用某个对象的方法,但想临时借给另一个对象使用
借用其他对象的方法(比如借用数组方法处理类数组对象)
明确知道参数个数,逐个传参
✅ 示例 1:借用对象方法
const person = {name: 'Alice',greet: function(greeting, punctuation) {console.log(`${greeting}, 我是 ${this.name}${punctuation}`);}
};const anotherPerson = { name: 'Bob' };// 我想用 person.greet 方法,但 this 指向 anotherPerson
person.greet.call(anotherPerson, '你好', '!');
// 输出:你好, 我是 Bob!
🔍 解析:
call
的第一个参数是 this 指向的对象(anotherPerson)后面的参数
'你好', '!'
是逐个传给greet
方法的
✅ 示例 2:类数组转数组(借用数组方法)
function example() {// arguments 是类数组,不是真正的数组const args = Array.prototype.slice.call(arguments);console.log(args);
}example(1, 2, 3); // [1, 2, 3]
✅ 2. 什么时候用 apply?
✅ 场景:你想要立即调用一个函数,明确指定 this 值,但参数是动态的、以数组(或类数组)形式存在
✅ 适用情况举例:
参数是数组或动态生成,不想一个个写
调用数学方法(如 Math.max / Math.min)并传入数组
和 call 类似,但参数通过数组传
✅ 示例 1:Math.max 传数组
const numbers = [1, 2, 3, 4];// Math.max(1, 2, 3, 4) ✅
// 但我们只有一个数组 [1, 2, 3, 4],怎么办?
const max = Math.max.apply(null, numbers);console.log(max); // 4
🔍 解析:
apply
第一个参数是 this(这里用 null,因为 Math.max 不依赖 this)第二个参数是数组
[1, 2, 3, 4]
,apply 会自动展开传给 max
✅ 示例 2:借用数组方法处理 arguments
function logArgs() {console.log(Array.prototype.join.apply(arguments, ['-', '-']));
}logArgs(1, 2, 3); // "1-2-3"
✅ 3. 什么时候用 bind?
✅ 场景:你不想立即调用函数,而是想先绑定 this(和/或部分参数),生成一个新的函数,稍后再调用
✅ 适用情况举例:
事件监听器中的 this 绑定(比如 React 类组件中的 onClick)
定时器 setTimeout/setInterval 中想固定 this
函数柯里化(提前传部分参数)
将函数作为回调传递时,确保 this 指向正确
✅ 示例 1:事件监听中的 this 绑定
const obj = {name: 'Alice',sayHi: function() {console.log(`Hi, 我是 ${this.name}`);}
};// 如果直接传 obj.sayHi 给 addEventListener,this 会指向 DOM 元素!
document.getElementById('myBtn').addEventListener('click', obj.sayHi.bind(obj));
🔍 解析:
bind(obj)
返回一个 新函数,其内部的 this 始终指向 obj即使稍后事件触发时,this 也不会跑偏
✅ 示例 2:定时器中固定 this
const obj = {name: 'Bob',showName: function() {console.log('My name is', this.name);}
};// 如果直接传 obj.showName,setTimeout 中的 this 会指向 window!
setTimeout(obj.showName.bind(obj), 1000); // 1秒后输出:My name is Bob
✅ 示例 3:函数柯里化(提前固定部分参数)
function multiply(a, b) {return a * b;
}// 创建一个新函数,固定第一个参数为 2
const double = multiply.bind(null, 2);console.log(double(5)); // 10 (即 2 * 5)
✅ 五、总结:什么时候用 bind / call / apply?(速查表)
方法 | 何时使用 | 是否立即执行 | 参数形式 | 主要场景 |
---|---|---|---|---|
call | 你想立即调用函数,并明确 this 指向,且参数是逐个传递的 | ✅ 立即执行 |
| 借用方法、明确 this 和少量参数 |
apply | 你想立即调用函数,并明确 this 指向,但参数是数组形式 | ✅ 立即执行 |
| 参数是数组、动态参数、数学函数 |
bind | 你不想立即调用函数,而是先绑定 this(和/或部分参数),生成新函数供后续调用 | ❌ 不立即执行,返回新函数 |
| 事件回调、定时器、柯里化、固定 this |