bind call apply函数

79 阅读4分钟

bind、call、apply 区别

call、apply 和 bind 都是 JavaScript 中用来改变函数执行上下文(this 值)的函数,它们之间的主要区别如下:

  1. call 和 apply 的第一个参数是要设置为新执行上下文的对象,第二个参数及以后的参数是要传递给函数的参数列表。而 bind 的第一个参数是要设置为新执行上下文的对象,后面的参数是原函数的参数列表。bind 返回一个新的函数,这个新函数会在调用时再将后面的参数传递给原函数。
  2. call 和 apply 都会立即执行函数,并且它们的返回值是函数的执行结果。而 bind 不会立即执行函数,而是返回一个新的函数,需要手动调用这个新函数才会执行原函数。
  3. call 和 apply 可以接受不定数量的参数,将这些参数打包成一个数组传递给原函数。而 bind 只接受原函数的参数列表,不会将其打包成数组。

call 和 apply 都是为了解决改变 this 的指向。作⽤都是相同的,只是传参的⽅式不同。 除了第⼀个参数外, call 可以接收⼀个参数列表, apply 只接受⼀个参数数组。

let a = {
 value: 1
}
function getValue(name, age) {
 console.log(name)
 console.log(age)
 console.log(this.value)
}
getValue.call(a, 'yck', '24')
getValue.apply(a, ['yck', '24'])

bind 和其他两个⽅法作⽤也是⼀致的,只是该⽅法会返回⼀个函数。并且我 们可以通过 bind 实现柯⾥化

柯里化(Currying)是计算机科学中的一种技术,其功能是将接受多个参数的函数变换成能接收单一参数(即原函数的第一个参数)的函数,并返回一个新的函数,这个新函数能接受余下的参数并返回结果。

例:

假设我们有一个函数,它接受两个参数并返回它们的和:

function add(a, b) {
  return a + b;
}

我们可以使用柯里化将这个函数转换为只接受一个参数的函数,并返回一个新的函数,该新函数接受第二个参数并返回结果:

function curryAdd(a) {
  return function(b) {
    return a + b;
  }
}

现在,我们可以像这样使用柯里化的函数:

const add5 = curryAdd(5); // 返回一个新函数,该函数接受一个参数并返回 5 + 参数值
console.log(add5(3)); // 输出 8

bind函数

Function 实例的 bind() 方法创建一个新函数,当调用该新函数时,它会调用原始函数并将其 this 关键字设置为给定的值,同时,还可以传入一系列指定的参数,这些参数会插入到调用新函数时传入的参数的前面

    /**
     * 手写bind方法
     *  1. 定义myBind方法
     *  2. 返回绑定this的新函数
     *  3. 合并绑定和新传入的参数
     * */

    //  1. 定义myBind方法
    Function.prototype.myBind = function (thisArg,...args){
        return (...reArgs)=>{
            // 2. 返回绑定this的新函数
          return this.call(thisArg,...args,...reArgs)
        }
    }

      // ------------- 测试代码 -------------
      const person = {
        name: "itheima",
      };

      function func(numA, numB, numC, numD) {
        console.log(this);//Object
        console.log(numA, numB, numC, numD);//1,2,3,4
        return numA + numB + numC + numD;
      }

      const bindFunc = func.myBind(person, 1, 2);

      const res = bindFunc(3, 4);
      console.log("返回值:", res);//返回值: 10

call函数

call() 函数在 JavaScript 中的作用是改变函数执行时的上下文(this 值),并立即执行该函数。它接受两个参数:第一个参数是要设置为新执行上下文的对象,第二个参数及以后的参数是要传递给函数的参数列表。

/**
     * 手写call方法
     *  1. 定义myCall方法
     *  2. 设置this并调用原函数
     *  3. 接收剩余参数并返回结果
     *  4. 使用Symbol调优
     * */
    // 1. 定义myCall方法
    // 3. 接收剩余参数并返回结果
    Function.prototype.myCall = function (thisArg, ...args) {
      // 2. 设置this并调用原函数
      // 给thisArg加一个一定和原属性不重名的新属性(方法)
      // 4. 使用Symbol调优
      const key = Symbol('key')
      // thisArg.key
      thisArg[key] = this
      const res = thisArg[key](...args)
      delete thisArg[key]
      return res
    }


    // ------------- 测试代码 -------------
    const food = {
      name: '西兰花炒蛋'
    }
    function func2(numA, numB, numC) {
      console.log(this)//object
      console.log(numA, numB, numC)//2,4,6
      return numA + numB + numC
    }
    const res2 = func2.myCall(food, 2, 4, 6)
    console.log('res2:', res2)//res2:12

    // ------------- 测试Symbol -------------
    // 调用Symbol内置函数,可以传入字符串作为标记
    // 返回一个唯一的值
    // const s1 = Symbol()
    // const s2 = Symbol()
    // console.log(s1 === s2)
    // const s3 = Symbol('itheima')
    // const s4 = Symbol('itheima')
    // console.log(s3 === s4)

apply函数

apply() 函数在 JavaScript 中的作用是改变函数执行时的上下文(this 值),并立即执行该函数。它接受两个参数:第一个参数是要设置为新执行上下文的对象,第二个参数是一个数组或类数组对象,其中的每个元素都将作为单独的参数传递给函数

 //1-定义一个apply函数
      //2-设置this调用原函数
      //3-接收剩余参数并返回结果
      Function.prototype.myApply = function (thisArg,args) {
        const key = Symbol('key')
        thisArg[key] = this
        const res = thisArg[key](...args)
        delete thisArg[key]
        return res
      };

      // ------------- 测试代码 -------------
      const food = {
        name: "西兰花炒蛋",
      };
      function func2(numA, numB) {
        console.log(this);//object
        console.log(numA, numB);//4,6
        return numA + numB;
      }
      const res2 = func2.myApply(food, [4, 6]);
      console.log("res2:", res2);//res2:10