前端开发–快速了解call()函数,apply( )函数,bind( )函数的使用与区别

  • Post author:
  • Post category:其他



#博学谷IT学习技术支持#


目录


call( )函数的基本使用


apply( )函数的基本使用


bind函数的基本使用


三个函数的比较


应用场景


求数组中的最大值与最小值


将arguments转换成数组


继承的实现


改变匿名函数的this指向


手写call、apply及bind函数


call方法的实现


apply函数的实现


bind函数的实现


拓展:为什么函数被称为一等公民?



call( )

函数,

apply( )

函数,

bind( )

函数,的作用都是改变

this

的指向,但是在使用方式上是有一定的区别的。

下面我们分别来看一下它们各自的使用方式:


call( )

函数的基本使用

基本语法如下:

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


function

表示的是:需要调用的函数。


thisObj

表示:

this

指向的对象,也就是

this

将指向

thisObj

这个参数,如果

thisObj

的值为

null

或者是

undefined

,则

this

指向的是全局对象。


arg1,arg2,..

表示:调用的函数需要的参数。

   function add(a, b) {
        console.log(this);
        console.log(a + b);
      }
      function sub(a, b) {
        console.log(a - b);
      }

      add.call(sub, 3, 1);// 调用add方法,但是add方法中的this指向的是sub,最终的输出结果是4


apply( )

函数的基本使用


apply()

函数的作用与

call()

函数的作用是一样的,不同的是在传递参数的时候有一定的差别

语法格式如下:

function.apply(thisObj,[argsArray])


function

表示的是:需要调用的函数。


thisObj

:

this

指向的对象,也就是

this

将指向

thisObj

这个参数,如果

thisObj

的值为

null

或者是

undefined

,则

this

指向的是全局对象。


[argsArray]

:表示的是函数需要的参数会通过数组的形式进行传递,如果传递的不是数组或者是arguments对象,会抛出异常。

  function add(a, b) {
        console.log(this); // 这里指向的是sub
        console.log(a + b);
      }
      function sub(a, b) {
        console.log(a - b);
      }

      add.apply(sub, [3, 1]); 


bind

函数的基本使用

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

通过上面语法格式,可以看出

bind

函数与

call

函数的参数是一样的。

不同 的是

bind

函数会返回一个新的函数,可以在任何时候进行调用。


      function add(a, b) {
        console.log(this); // 这里指向的是sub
        console.log(a + b);
      }
      function sub(a, b) {
        console.log(a - b);
      }

      var newFun = add.bind(sub, 3, 1); //bind 返回的是一个新的函数。
      newFun();//完成对add函数的调用,同时this指向了sub

三个函数的比较

通过前面对三个函数的基本使用,可以看出,它们共同点就是改变

this

的指向。

不同点:


call()

函数与

apply()

函数,会立即执行函数的调用,而

bind

返回的是一个新的函数,可以在任何时候进行调用。


call()

函数与

bind

函数的参数是一样的,而

apply

函数第二个参数是一个数组或者是

arguments

对象。

应用场景

这里,我们重点看一下,关于

call()

函数,

bind()

函数,

apply()

函数的应用场景。


求数组中的最大值与最小值

 var arr = [3, 6, 7, 1, 9];
      console.log(Math.max.apply(null, arr));
      console.log(Math.min.apply(null, arr));




arguments

转换成数组

   function fn() {
        var arr = Array.prototype.slice.call(arguments);
        arr.push(6);
        return arr;
      }
      console.log(fn(1, 2));


继承的实现

function Person(userName, userAge) {
        this.userName = userName;
        this.userAge = userAge;
      }
      function Student(name, age, gender) {
        Person.call(this, name, age);
        this.gender = gender;
      }
      var student = new Student("zhangsan", 20, "男");
      console.log(
        "userName=" +
          student.userName +
          ",userAge=" +
          student.userAge +
          ",gender=" +
          student.gender
      );


改变匿名函数的

this

指向

  var person = [
        { id: 1, userName: "zhangsan" },
        { id: 2, userName: "lisi" },
      ];
      for (var i = 0; i < person.length; i++) {
        (function (i) {
          this.print = function () {
            console.log(this.id);
          };
          this.print();
        })(i);
      }

具体的实现方式如下:

    var person = [
        { id: 1, userName: "zhangsan" },
        { id: 2, userName: "lisi" },
      ];
      for (var i = 0; i < person.length; i++) {
        (function (i) {
          this.print = function () {
            console.log(this.id);
          };
          this.print();
        }.call(person[i], i));
      }

手写call、apply及bind函数



call

方法的实现


      Function.prototype.myCall = function (context) {
       
        var args = [...arguments].slice(1);
       
        context = context || window;
        
        context.fn = this;
     
        var result = context.fn(...args);
        return result;
      };
      function Add(num1, num2) {
        console.log(this);
        console.log(num1 + num2);
      }
      function Sub(num1, num2) {
        console.log(num1 - num2);
      }
      Add.myCall(Sub, 6, 3);



apply

函数的实现

 Function.prototype.myApply = function (context) {
        var result = null;
        context = context || window;
        context.fn = this;
        if (arguments[1]) {
          // console.log("arguments=", arguments[1]);// arguments= (2) [6, 3]
          result = context.fn(...arguments[1]);
        } else {
          result = context.fn();
        }
        return result;
      };
      function Add(num1, num2) {
        console.log(this);
        console.log(num1 + num2);
      }
      function Sub(num1, num2) {
        console.log(num1 - num2);
      }
      Add.myApply(Sub, [6, 3]);



bind

函数的实现

   Function.prototype.myBind = function (context) {
        // 获取参数
        var args = [...arguments].slice(1), // [1,5]
          fn = this;
        // console.log(this);//Add
        return function Fn() {
          // console.log(this); //Window
          return fn.apply(context, args);
        };
      };
      function Add(num1, num2) {
        console.log(this);
        console.log(num1 + num2);
      }
      function Sub(num1, num2) {
        console.log(num1 - num2);
      }
      var newFun = Add.myBind(Sub, 1, 5);
      newFun();
  <script>
      function add(a, b) {
        console.log(this); // 这里指向的是sub
        console.log(a + b);
      }
      function sub(a, b) {
        console.log(a - b);
      }

      var newFun = add.bind(sub, 3); //bind 返回的是一个新的函数。
      newFun(2); //完成对add函数的调用,同时this指向了sub
    </script>

实现关于

myBind

方法参数的模拟

    Function.prototype.myBind = function (context) {
        // 获取参数
        var args = [...arguments].slice(1),
          fn = this;
        // console.log(this);//Add
        return function Fn() {
          // console.log(this); //Window
          //这里是调用bind函数的时候传递的参数,将其转换成数组
          var bindArgs = Array.prototype.slice.call(arguments);
          //下面完成参数的拼接
          return fn.apply(context, args.concat(bindArgs));
        };
      };
      function Add(num1, num2) {
        console.log(this);
        console.log(num1 + num2);
        return 10;
      }
      function Sub(num1, num2) {
        console.log(num1 - num2);
      }
      var newFun = Add.myBind(Sub, 1);
      console.log(newFun(8));

拓展:为什么函数被称为一等公民?

JavaScript 语言将函数看作一种值,与其它值(数值、字符串、布尔值等等)地位相同。凡是可以使用值的地方,就能使用函数。比如,可以把

函数赋值给变量和对象的属性

,也可以当作

参数传入其他函数

,或者

作为函数的结果返回

同时函数还可以作为类的构造函数,完成对象实例的创建。所以说,这种多重身份让

JavaScript

中的函数变得非常重要,所以说函数被称为一等公民。



版权声明:本文为weixin_51059952原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。