【study】call,apply,bind区别

83 阅读2分钟
  1. call
  • 用途:调用一个函数,并且改变函数的 this 指向。
  • 参数:第一个参数是 this 的值,其余参数是要传递给函数的参数列表。
// 语法: function.call(thisArg, arg1, arg2, ...)

// 使用场景:当你有一组参数,并且想立即调用函数时使用
function sayHello() {
  console.log(`Hello, ${this.name}`);
}

const person = { name: 'Bob' };
sayHello.call(person); // "Hello, Bob"
  • 手撕
Function.prototype.myCall = function (obj, ...args) {
      var obj = obj || window // 这里只能用var
      const p = Symbol('p')
      obj.p = this
      const res = obj.p(...args)
      delete obj.p
      return res
 }

  1. apply
  • 用途:调用一个函数,并且改变函数的 this 指向。
  • 参数:第一个参数是 this 的值,第二个参数是一个包含要传递给函数的参数的数组或类数组对象。
// 语法: function.apply(thisArg, [argsArray])

// 使用场景:当你有一个数组或类数组对象,并且想立即调用函数时使用
function sum(a, b, c) {
  return a + b + c;
}

const numbers = [1, 2, 3];
console.log(sum.apply(null, numbers)); // 6
  • 手撕
Function.prototype.myApply = function (obj, ...args) {
      var obj = obj || window
      const p = Symbol('p')
      obj.p = this
      const res = obj.p(...args[0]) // 立即执行,和apply的区别!!!!!!!
      delete obj.p
      return res
}

  1. bind
  • 用途:创建一个新的函数,该函数在被调用时,其 this 值是特定的值,并且预设一些参数。
  • 参数:第一个参数是 this 的值,后续参数是预设的参数列表。
// 语法: const boundFunction = function.bind(thisArg, arg1, arg2, ...)

// 使用场景:当你想创建一个新的函数,并且稍后调用它,且this和部分参数是预设时使用
const module = {
  x: 42,
  getX: function() {
    return this.x;
  }
};

const unboundGetX = module.getX;
console.log(unboundGetX()); // undefined

const boundGetX = unboundGetX.bind(module);
console.log(boundGetX()); // 42

  • 手撕
  Function.prototype.myBind = function (context) {
    // 保存this,即原函数
    var fn = this;
    
    if (typeof fn !== 'function') {
      throw new TypeError('Error');
    }

    // 获取除了第一个参数context外的所有参数
    var args = Array.prototype.slice.call(arguments, 1);

    // 返回一个新的函数
    function boundFunc() {
      // 获取调用返回函数时的参数
      var bindArgs = Array.prototype.slice.call(arguments);
      // 合并参数并调用原函数
      return fn.apply(this instanceof boundFunc ? this : context, args.concat(bindArgs));
    }

    // 设置原型链,支持继承
    boundFunc.prototype = Object.create(fn.prototype);

    return boundFunc;
  };

  1. 区别总结:
    1. call 和 apply

    • 都是立即调用函数,并且改变该函数的 this 指向。

    • 区别:

      • call 逐个传递参数。
      • apply 使用一个数组(或类数组对象)传递参数。
    1. bind

    • 不会立即调用函数,而是返回一个新的函数。
    • 返回的新函数在调用时,其 this 值是特定的值,并且可以拥有预设的参数。