JavaScript 中的call()、apply()、bind()的用法 | 青训营

66 阅读2分钟

JavaScript 中的call()apply()bind()的用法

相同

bind、apply、call 是函数调用时动态地改变函数的上下文(改变函数执行时this的指向),同时还可以传参,调用它们的对象必须是一个函数 Function

不同(主要体现在传参上):

call

call 函数允许你在一个特定的上下文中调用一个函数。它的语法如下:

  function.call(context, arg1, arg2, ...)

apply

apply 函数与 call 函数类似,它也允许你在一个特定的上下文中调用一个函数。不同之处在于,apply 函数需要将参数作为数组传递。它的语法如下:

  function.apply(context, [argsArray])

bind

bind 函数与 callapply 函数不同,它不会立即调用函数。相反,它返回一个新函数,该函数将绑定到指定的上下文,当该函数被调用时,它将以指定的上下文运行。它的语法如下:

  function.bind(thisArg, arg1, arg2, ...)

EXAMPLE

  • example1

      
      let name = 'LiHua', age = 20;
      ​
      function printInfo() {
          console.log(this);
          console.log('My name is ' + name + ', I am ' + age + ' years old.');
      }
      ​
      printInfo();
    

    输出:My name is LiHua, I am 20 years old.

    此时的printInfo()函数全局声明,this指向window

  • example2

      
      const name = 'LiHua', age = 20;
      let obj = {
          name: 'Mike',
          hello: function() {
              console.log('My name is ' + this.name + ', I am ' + this.age + ' years old.');
          }
      };
      obj.hello();
    

    输出:My name is Mike, I am undefined years old.

    此时hello中的this指向obj

  • example3

    重定义 this 这个对象

      
      const name = 'LiHua', age = 20;
      let obj = {
          name: 'Mike',
          objage: this.age,
          hello: function() {
              console.log('My name is ' + this.name + ', I am ' + this.age + ' years old.');
          }
      };
      let newObj = {
          name: 'Karry',
          age: 50,
      };
      ​
      obj.hello.call(newObj);
      obj.hello.apply(newObj);
      obj.hello.bind(newObj)();
    

    输出:

    My name is Karry, I am 50 years old.

    My name is Karry, I am 50 years old.

    My name is Karry, I am 50 years old.

    call、bind、apply这三个函数的第一个参数都是 this 的指向对象 ,其中bind返回的是一个新的函数,你必须调用它才会被执行

  • example4

    传参情况下

      
      const name = 'LiHua', age = 20;
      let newObj = {
          name: 'Karry',
          age: 50,
      };
      let fun = {
          name: 'Mike',
          objage: this.age,
          hello: function(from, to) {
              console.log('My name is ' + this.name + ', I am ' + this.age + ' years old.' + 'I am from ' + from + '. I am going to ' + to + '.');
          }
      }
      fun.hello.call(newObj, 'BeiJing', 'ShangHai');
      fun.hello.call(newObj, ['BeiJing', 'ShangHai']);
      fun.hello.apply(newObj, ['BeiJing', 'ShangHai']);
      fun.hello.bind(newObj, 'BeiJing', 'ShangHai')();
      fun.hello.bind(newObj, ['BeiJing', 'ShangHai'])();
    

    输出:

    My name is Karry, I am 50 years old.I am from BeiJing. I am going to ShangHai.

    My name is Karry, I am 50 years old.I am from BeiJing,ShangHai. I am going to undefined.

    My name is Karry, I am 50 years old.I am from BeiJing. I am going to ShangHai.

    My name is Karry, I am 50 years old.I am from BeiJing. I am going to ShangHai.

    My name is Karry, I am 50 years old.I am from BeiJing,ShangHai. I am going to undefined.

    call、bind、apply这三个函数的第一个参数都是this的指向对象,第二个参数则有些差距:

    • call的参数是直接放进去的,第二个...第 n 个参数全都用逗号分隔,直接放到后面
    • apply的所有参数都必须放在一个数组里面传进去
    • bind除了返回是函数以外,它 的参数和 call 一样

    三者的参数不限定是 string 类型,允许是各种类型,包括函数、object