In Javascript, the method of changing this inside the function: call(), apply(), bind()

Before sorting out the methods of changing the this point inside the function in Javascript, let me introduce the calling methods of different functions and the point of this inside the function.

1. How to call the function

  1. Ordinary function
  2. object method
  3. Constructor
  4. bind event function
  5. timer function
  6. Execute the function immediately
<script>
        // 函数的调用方式

        // 1. 普通函数
        function fn() {
            console.log('人生的巅峰');
        }
        // 调用函数
        // fn(); fn.call();

        // 2. 对象的方法
        var o = {
            sayHi: function() {
                cconsole.log('人生的巅峰');
            }
        }

        // 调用函数
        o.sayHi();

        // 3. 构造函数
        function Star() {};
        // 调用函数
        new Star();

        // 4. 绑定事件函数
        btn.onclick = function() {}; // 点击了按钮就可以调用这个函数

        // 5. 定时器函数
        setInterval(function() {}, 2000); // 这个函数是定时器自动2秒钟调用一次

        // 6. 立即执行函数
        //第一种写法
        (function() {
            console.log('人生的巅峰');
        })();

        //第二种写法
        (function() {
            cconsole.log('人生的巅峰');
        }());

        // 立即执行函数是自动调用
    </script>

2. The point of this in the function

  • The this point is determined when we call the function. The different calling methods determine the different pointing of this. Generally, we point to our caller.

3. Change the internal this point of the function

  • JavaScript provides us with some function methods to help us deal with the pointing problem of this inside the function. There are  three methods commonly used bind()call(),  .apply()

3.1, call () method

The call() method can immediately call a function , and can change the this point of the function .

Usage: fun.call(thisArg,arg1,arg2,…)

  • thisArg : the this value specified when the fun function is running
  • arg1,arg2,… ​​: other arguments
  • Return value : It is the return value of the fun function, because it is the calling function

So when we want to change the point of this and call this function at the same time, we can use call, such as inheritance.
 

   <script>
        // 改变函数内this指向 js提供了三种方法  call() apply() bind()

        // 1. call()
        var o = {
            name: 'andy'
        }

        function fn(a, b) {
            console.log(this);
            console.log(a + b);
        }
        fn.call(o, 1, 2);
        // call 第一个可以调用函数 第二个可以改变函数内的this 指向
        // call 的主要作用可以实现继承
        function Father(uname, age, sex) {
            this.uname = uname;
            this.age = age;
            this.sex = sex;
        }

        function Son(uname, age, sex) {
            Father.call(this, uname, age, sex);
        }

        var son = new Son('刘德华', 18, '男');
        console.log(son);
    </script>

The Son constructor wants to inherit the properties of the Father constructor. In the Son constructor, the Father constructor is called, and at the same time, the this point is changed to point to the Son constructor. This time the call function is used.

The process of realizing inheritance: create an instantiated object son of Son, and then pass 'xiaoming' and 18 to uname and age in function Son(uname, age) respectively, at this time the formal parameter uname='xiaoming'; age= 18; Then there is a function Father.call(this, uname, age) in function Son(uname, age), where uname and age are formal parameters, so they also have corresponding values ​​at this time, and then the first parameter is changed to For this, this in the Son constructor should point to its instantiated object, which is the son here. Call the Father function with these three parameters, that is, the uname attribute of son is assigned the value 'xiaoming' of the formal parameter uname, and the attribute of son is assigned the value 18 of the formal parameter age. Inheritance is implemented.

3.2, apply () method

The apply() method can call a function immediately , and can change the this point of the function .

How to use: fun.apply(thisArg,[argsArray])

  • thisArg : the this value specified when the fun function is running
  • [argsArray] : passed value, array or pseudo-array form
  • Return value : It is the return value of the fun function, because it is the calling function

Because the parameter it passes in is an array , we can use it to deal with some array-related problems , such as borrowing Math.max() to find the maximum/minimum value of the array.

    <script>
        // 改变函数内this指向 js提供了三种方法 call() apply() bind()

        // 2. apply() 应用 运用的意思
        var o = {
            name: 'andy'
        };

        function fn(arr) {
            console.log(this);
            console.log(arr); // 打印出来的不是数组,而是字符串pink
        }
        fn.apply(o, ['pink']);
        // 1. 第一个也是调用函数 第二个可以改变函数内部的this指向
        // 2. 但是它的参数必须是数组(伪数组)
        // 3. apply 的主要应用  比如说我们可以利用 apply 借助于数学内置对象求最大值
        // Math.max();
        var arr = [1, 66, 3, 99, 4];
        // var max = Math.max.apply(null, arr);
        var max = Math.max.apply(Math, arr);
        var min = Math.min.apply(Math, arr);
        console.log(max, min);
        // 如果传递的数组里面是字符串型的,打印出来的就是字符串型的;如果传递的数组里面是数字型的,打印出来的就是数字型的
    </script>

Math.max is a method (function), and the apply method is used for it. There is no need to change the this point here, so the first parameter lets it point back to Math, and the second parameter can be passed in to the array to be processed. In this way, you can use the Math method to process the array.

The apply method will automatically process the incoming array into the corresponding data type.

3.3, bind () method

The bind function does not call the function directly , but it can change the this pointer inside the function , which is widely used.

How to use: fun.bind(thisArg,arg1,arg2,…)

  • thisArg : the this value specified when the fun function is running
  • arg1,arg2,… ​​: other arguments
  • Return value : A copy of the original function transformed from the specified this value and initialization parameters , that is to say, the return value is a function

Therefore, when we just want to change the this point and do not want to call this function immediately, we can use bind, such as changing the this point of the timer .

For example, there is a requirement that after a button is clicked, the button is disabled and returns to normal after 2 seconds. Here the this in the timer points to the window, and we want it to point to the currently clicked button, so we need to modify the this point, but we don't want it to be called immediately, but to wait until the condition of the timer is met. So use the bind function .

There is a very clever point here, so this in function () { this.disabled = false; }.bind(this) is already outside the timer, so it no longer points to window, and the environment outside the timer is The button click event means that this points to the currently clicked btn, and through the bind function, the this point of the timer function is cleverly changed to the currently clicked btn to realize the current function.

<body>
    <button>点击</button>
    <button>点击</button>
    <button>点击</button>
    <script>
        // 3. bind()
        var o = {
            name: 'andy'
        };
        function fn(a, b) {
            console.log(this);
            console.log(a + b);
        };
        var f = fn.bind(o, 1, 2);
        f();  // 3
        // 1. 不会调用原来的函数 可以改变原来函数内部的this 指向
        // 2. 返回的是原函数改变this之后产生的新函数
        // 3. 如果有的函数我们不需要立即调用,但是又想改变这个函数内部的this指向 此时用bind
        // 4. 我们有一个按钮,当我们点击了之后,就禁用这个按钮,3秒钟之后开启这个按钮
        // var btn1 = document.querySelector('button');
        // btn1.onclick = function() {
        //     this.disabled = true; // 这个this 指向的是 btn 这个按钮
        //     // var that = this;   // 方法1
        //     setTimeout(function() {
        		    // 定时器函数里面的this 指向的是window
        //         // that.disabled = false;    // 方法1
        		   // 方法2:用bind()改变this指向,bind在setTimeout函数的外面
        //         this.disabled = false; // 此时定时器函数里面的this 指向的是btn
        //     }.bind(this), 3000); // 这个this 指向的是btn 这个对象
        // }
        var btns = document.querySelectorAll('button');
        for (var i = 0; i < btns.length; i++) {
            btns[i].onclick = function() {
                this.disabled = true;
                setTimeout(function() {
                    this.disabled = false;
                }.bind(this), 3000);
            }
        }
    </script>
</body>

3.4 Summary of call(), apply(), bind()

Same point:

  • can change the this point inside the function

difference:

  • call and apply  will call the function immediately, the return value is the return value after the function is executed, and change the this point inside the function
  • The parameters passed by call and apply are different, call passes parameters, and apply must be in the form of an array
  • bind  will not call the function immediately, the return value is a function, the modified copy of the original function can change the internal this point of the function
  • bind  is to return the corresponding function, which is convenient to call later; apply and call are to call immediately
  • The parameters passed by call and bind  are the new this pointer and other parameters of the original function, and the parameters passed by apply are the new this pointer and an array

Main application scenarios:

  • call often does inheritance
  • apply is often related to arrays, such as realizing the maximum and minimum values ​​of the array by means of mathematical alignment
  • bind  does not call the function, but still wants to change the this point, such as changing the this point inside the timer

Guess you like

Origin blog.csdn.net/DIUDIUjiang/article/details/126500855