返回

call、bind、apply的区别与实现原理

前端

前言

在JavaScript中,函数调用是一种非常重要的操作。我们可以通过函数调用来执行一段代码,并传递一些参数给函数。函数调用可以分为两种:直接调用和间接调用。直接调用是指我们直接使用函数名来调用函数,而间接调用是指我们通过一个变量或者表达式来调用函数。

call、bind和apply都是JavaScript中常用的函数调用方法。这三个方法都可以实现间接调用,但它们之间还是存在着一些区别的。

call、bind、apply的区别

1. 参数传递方式

  • call方法的第一个参数也是this的指向,后面传入的是一个参数列表。
  • bind方法的第一个参数也是this的指向,但它不会立即执行函数,而是返回一个新的函数。这个新的函数在被调用时,this的指向会变成bind方法的第一个参数。
  • apply方法的第一个参数也是this的指向,后面传入的是一个数组,数组中的元素就是函数的参数。

2. 执行时机

  • call方法改变this指向后原函数会立即执行。
  • bind方法只是临时改变this指向一次,当第一个参数为null、undefined的时候,this会指向window对象。
  • apply方法改变this指向后原函数也会立即执行。

3. 返回值

  • call方法和apply方法都会返回函数调用的结果。
  • bind方法不会返回任何值。

call、bind、apply的实现原理

1. call方法的实现原理

Function.prototype.call = function(context) {
  var args = [];
  for (var i = 1; i < arguments.length; i++) {
    args.push(arguments[i]);
  }
  context.fn = this;
  var result = context.fn(...args);
  delete context.fn;
  return result;
};

2. bind方法的实现原理

Function.prototype.bind = function(context) {
  var fn = this;
  var args = [];
  for (var i = 1; i < arguments.length; i++) {
    args.push(arguments[i]);
  }
  return function() {
    context.fn = fn;
    var result = context.fn(...args);
    delete context.fn;
    return result;
  };
};

3. apply方法的实现原理

Function.prototype.apply = function(context, args) {
  context.fn = this;
  var result = context.fn(...args);
  delete context.fn;
  return result;
};

总结

call、bind和apply都是JavaScript中常用的函数调用方法。这三个方法都可以实现间接调用,但它们之间还是存在着一些区别的。

  • call方法的第一个参数也是this的指向,后面传入的是一个参数列表。改变this指向后原函数会立即执行。
  • bind方法的第一个参数也是this的指向,但它不会立即执行函数,而是返回一个新的函数。这个新的函数在被调用时,this的指向会变成bind方法的第一个参数。
  • apply方法的第一个参数也是this的指向,后面传入的是一个数组,数组中的元素就是函数的参数。改变this指向后原函数也会立即执行。

这三个方法在实际开发中都有着广泛的应用。我们可以根据不同的需求来选择使用不同的方法。