JS改变this指向常用call()、apply()、bind()方法应用及手写实现

一、应用场景

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

var arr = [3, 6, 7, 1, 9];

 console.log(Math.max.apply(null, arr));

 console.log(Math.min.apply(null, arr));

2、将arguments转换成数组   

function fn() {

      var arr = Array.prototype.slice.call(arguments);

        arr.push(6);

        return arr;

      }

 console.log(fn(1, 2));

3、继承的实现

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

      );

4、改变匿名函数的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();

        }.call(person[i], i));

     }

二、手写call、apply、bind函数

1、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);

2、apply方法实现

Function.prototype.myApply = function (context) {

        var result = null;

        context = context || window;

        context.fn = this;

        if (arguments[1]) {

          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]);

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();

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));

猜你喜欢

转载自blog.csdn.net/m0_65835778/article/details/125380197