-
相同点
-
功能目的相同:
bind
、call
和apply
都是用于改变函数内部this
的指向,使得函数可以在特定的对象上下文中被调用,从而能够访问和操作该对象的属性。 -
都和函数调用相关:它们都是函数对象的方法,并且在函数调用的场景下发挥作用,通过这些方法能够灵活地控制函数执行时的
this
指向。
-
-
区别
调用方式、参数传递形式、返回值不同
call 和 apply:它们会立即执行函数,并返回函数的执行结果。
bind:它并不立即执行函数,而是返回一个新的函数。这个新函数在被调用时,内部的this指向已经被绑定到指定的对象上,并且可以根据bind时传递的参数情况来接收剩余的参数。
call |
语法为 |
function add(num1, num2) { } let obj = {value: 10}; console.log(add.call(obj, 20, 30)); | 这里add.call(obj, 20, 30) 会将add 函数内部的this 指向obj ,并将20 和30 作为参数传递给add 函数,最终返回60 |
apply | 语法为函数名.apply(对象, [参数数组]) 。它也接受一个对象作为第一个参数来指定this 的指向,但第二个参数必须是一个包含函数参数的数组。 |
function add(num1, num2) { return this.value + num1 + num2; } let obj = {value: 10}; console.log(add.apply(obj, [20, 30])); | 同样是将add 函数内部的this 指向obj ,不过参数是通过一个数组[20, 30] 的形式传递的,最终也返回60 |
bind | 语法为函数名.bind(对象, 参数1, 参数2,...) 。它返回一个新的函数,这个新函数内部的this 已经绑定到指定的对象上。可以立即调用这个新函数,也可以将它保存起来稍后调用。如果在bind 时传递了参数,这些参数会被固定下来作为新函数的部分参数。 |
function add(num1, num2) { return this.value + num1 + num2; } let obj = {value: 10}; let newAdd = add.bind(obj, 20); console.log(newAdd(30)); | 首先add.bind(obj, 20) 会返回一个新函数newAdd ,这个新函数内部的this 已经指向obj ,并且第一个参数已经固定为20 。当调用newAdd(30) 时,相当于调用add 函数,this 指向obj ,参数为20 和30 ,最终返回60 |
3. 如何确定在 JavaScript 中使用 call、apply 还是 bind 方法?
1) 是否需要立即执行函数
** 立即执行选择 call 或 apply
例如,你有一个函数用于计算两个数与对象中某个属性值的总和,并且你想在特定对象上下文中立即计算结果:
function sum(num1, num2) {
return this.value + num1 + num2;
}
let obj1 = {value: 10};
let obj2 = {value: 20};
// 使用call
console.log(sum.call(obj1, 30, 40));
// 使用apply
console.log(sum.apply(obj2, [50, 60]));
** 延迟执行选择 bind
例如,你有一个事件处理函数,需要在特定对象上下文中执行,但你只想先绑定this
指向,等到事件触发时再执行:
function handleClick() {
console.log(this.name +'clicked');
}
let buttonObj = {name: 'Submit Button'};
let boundHandleClick = handleClick.bind(buttonObj);
document.addEventListener('click', boundHandleClick);
2) 参数传递方式的便利性
** 参数逐个传递用 call
例如,有一个函数用于显示用户信息,包括姓名、年龄和城市,并且你想在某个用户对象的上下文中调用这个函数:
function showUserInfo(name, age, city) {
console.log(`Name: ${this.userName}, Name: ${name}, Age: ${age}, City: ${city}`);
}
let userObj = {userName: 'John'};
showUserInfo.call(userObj, 'Alice', 25, 'New York');
** 参数以数组形式存在用 apply
例如,你有一个函数用于计算一组数字的总和,并且这些数字存储在一个数组中:
function sumArray(numbers) {
return numbers.reduce((total, num) => total + num);
}
let numberArray = [1, 2, 3, 4, 5];
console.log(sumArray.apply(null, [numberArray]));