call、bind、apply区别

简介: 【10月更文挑战第26天】`call`、`bind` 和 `apply` 方法在改变函数 `this` 指向和参数传递方面各有特点,开发者可以根据具体的需求和使用场景选择合适的方法来实现更灵活和高效的JavaScript编程。

在JavaScript中,callbindapply 都是用于改变函数内部 this 指向的方法,它们的功能相似,但在使用方式和一些细节上存在区别:

语法和基本使用

  • call 方法call 方法的语法是 function.call(thisArg, arg1, arg2,...)。它接受一个 thisArg 参数作为函数执行时的 this 指向,后面可以跟多个参数,这些参数将作为被调用函数的实参传递给函数。例如:
function add(num1, num2) {
   
  return this.sum + num1 + num2;
}

var obj = {
    sum: 10 };
var result = add.call(obj, 5, 3);
console.log(result);

在上述示例中,add 函数通过 call 方法将 this 指向了 obj 对象,并传递了参数 53,最终返回计算结果 18

  • apply 方法apply 方法的语法是 function.apply(thisArg, [argsArray])。它也接受一个 thisArg 参数来指定 this 的指向,第二个参数是一个数组或类数组对象,其中的元素将作为被调用函数的实参传递给函数。例如:
function multiply(num1, num2) {
   
  return this.product * num1 * num2;
}

var anotherObj = {
    product: 5 };
var numbers = [2, 3];
var result = multiply.apply(anotherObj, numbers);
console.log(result);

在这个示例中,multiply 函数使用 apply 方法将 this 指向 anotherObj,并将数组 numbers 中的元素作为参数传递给函数,得到结果 30

  • bind 方法bind 方法的语法是 function.bind(thisArg, arg1, arg2,...)。它同样接受一个 thisArg 参数来绑定 this 指向,后面也可以跟多个参数,这些参数会在函数被调用时作为预设的参数传递给函数,但 bind 方法不会立即执行函数,而是返回一个新的函数,需要手动调用这个新函数才能执行原函数的逻辑。例如:
function subtract(num1, num2) {
   
  return this.difference - num1 - num2;
}

var yetAnotherObj = {
    difference: 20 };
var boundSubtract = subtract.bind(yetAnotherObj, 7);
var result = boundSubtract(3);
console.log(result);

在上述示例中,subtract 函数通过 bind 方法绑定了 this 指向 yetAnotherObj,并预设了参数 7,返回一个新的函数 boundSubtract,当调用 boundSubtract 并传递参数 3 时,得到结果 10

主要区别

调用方式和返回值

  • callapplycallapply 方法都会立即调用函数,并返回函数的执行结果。它们的区别主要在于传递参数的方式不同,call 是逐个传递参数,而 apply 是将参数作为数组传递。
  • bindbind 方法不会立即执行函数,而是返回一个新的函数,需要在后续手动调用这个新函数来执行原函数的逻辑,并且可以根据需要再次传递其他参数。

参数传递方式

  • callcall 方法的参数是逐个列出的,除了第一个参数用于指定 this 指向外,后面的参数按照函数定义的参数顺序依次传递。这种方式在参数较少且明确的情况下比较直观和方便。
  • applyapply 方法的第二个参数必须是一个数组或类数组对象,数组中的元素将作为函数的实参传递给函数。这种方式在参数较多或者参数是一个数组的情况下比较方便,可以直接将数组作为参数传递,而不需要逐个列出参数。
  • bindbind 方法在绑定 this 指向的同时,可以预设部分参数,这些参数将固定在返回的新函数中。当调用新函数时,可以继续传递其他参数,这些后续传递的参数将与预设参数一起作为函数的实参进行计算。

应用场景

callapply 的应用场景

  • 当需要临时改变函数内部的 this 指向,并立即调用函数获取结果时,可以使用 callapply 方法。例如,在使用一些原生的JavaScript对象方法时,可能需要改变方法内部的 this 指向来满足特定的需求。
var numbers = [5, 10, 15];
var max = Math.max.apply(null, numbers);
console.log(max);

在上述示例中,使用 apply 方法将 Math.max 函数的 this 指向设置为 null,并将数组 numbers 作为参数传递给 Math.max 函数,从而获取数组中的最大值。

  • 当调用一个函数,并且参数已经存在于一个数组中时,使用 apply 方法可以更简洁地传递参数。例如,在处理函数的可变参数时,可以将参数收集到一个数组中,然后使用 apply 方法来调用函数。
function sumAll() {
   
  var args = Array.prototype.slice.call(arguments);
  return args.reduce(function (total, num) {
   
    return total + num;
  }, 0);
}

var numbersToSum = [1, 2, 3, 4, 5];
var result = sumAll.apply(null, numbersToSum);
console.log(result);

在这个示例中,首先使用 Array.prototype.slice.call(arguments) 将函数的可变参数转换为数组,然后使用 apply 方法将数组中的元素作为参数传递给 sumAll 函数进行求和计算。

bind 的应用场景

  • 当需要将函数的 this 指向固定,并且在后续的不同地方多次调用该函数时,bind 方法非常有用。它可以创建一个具有特定 this 指向和预设参数的新函数,方便在不同的上下文中重复使用。
var button = document.getElementById('myButton');
button.addEventListener('click', function () {
   
  console.log('Button clicked');
}.bind(this));

在上述示例中,使用 bind 方法将点击事件处理函数的 this 指向绑定到当前的上下文,确保在事件处理函数中能够正确地访问和操作当前上下文中的变量和方法。这样,无论在何处定义和使用这个点击事件处理函数,其 this 指向都始终保持一致。

  • 在一些需要延迟执行函数或者需要将函数作为回调函数传递,并且希望固定函数的 this 指向和部分参数的场景中,bind 方法也很常用。
function greet(name) {
   
  console.log('Hello, ' + name);
}

var greetJohn = greet.bind(null, 'John');
setTimeout(greetJohn, 1000);

在这个示例中,使用 bind 方法创建了一个新的函数 greetJohn,将 greet 函数的 this 指向设置为 null,并预设了参数 'John'。然后将 greetJohn 函数作为回调函数传递给 setTimeout,延迟一秒后执行,实现了在延迟一段时间后以固定的参数和 this 指向调用 greet 函数的效果。

callbindapply 方法在改变函数 this 指向和参数传递方面各有特点,开发者可以根据具体的需求和使用场景选择合适的方法来实现更灵活和高效的JavaScript编程。

目录
相关文章
|
1月前
|
前端开发 JavaScript
比较一下apply/call/bind ?
本文首发于微信公众号“前端徐徐”,详细介绍了 JavaScript 中 `apply`、`call` 和 `bind` 方法的概念、使用场景及手动实现。主要内容包括: - **apply**:使用数组作为参数调用函数,并指定 `this`。 - **call**:直接传递参数调用函数,并指定 `this`。 - **bind**:返回一个绑定了 `this` 和部分参数的新函数。 文章还对比了这三个方法的区别,并提供了手动实现的代码示例。
16 2
|
5月前
|
JavaScript 前端开发
call和apply的区别
call和apply的区别
|
6月前
call\apply\bind详解
call\apply\bind详解
32 0
bind、call、apply 区别
bind、call、apply 区别
78 0
call、apply、bind笔记
call、apply、bind笔记
62 0
|
JavaScript 前端开发
关于 this 指向、如何实现 new call apply bind 我所知道的
关于 this 指向、如何实现 new call apply bind 我所知道的
80 0
apply、bind和call
apply、bind和call
88 0
|
JavaScript 前端开发
一文搞定this、apply、call、bind
一文搞定this、apply、call、bind