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

#博学谷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中的函数变得非常重要,所以说函数被称为一等公民。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值