js函数的this指向的改变(call,apply,bind)

61 阅读1分钟

js 为我们提供了call,apply,bind等改变this指向的方法,之前说过的,js函数的this指向在不同的情况下有不同的指向;但是我们在工作当中有很多情况下需要用到其他函数的this,所以这个时候call,apply,bind等方法的作用就体现出来了。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>call改变this指向的方式</title>
</head>

<body>
    <script>
        var obj = {
            name: '张三',
            age: 20,
            say: function () {
                console.log(this.name);
            }
        };

        function add(a, b) {
            console.log(a, b);
            console.log(this.name);
        }
        //后面跟着参数列表
        //会直接执行add函数
        add.call(obj, 25, 54);

        function Farector(name, age) {
            this.name = name;
            this.age = age;
        }
        //用call方法来做继承
        function Son(uname, age) {
            Farector.call(this, uname, age);
            console.log(this);
        }
        
        var s1 = new Son('李四', 20);
        console.log(s1.name);
        console.log(Son.name);

    </script>

</body>

</html>

apply

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>apply</title>
</head>

<body>
    <script>
        var obj = {
            name: '张三',
            age: 20,
            say: function () {
                console.log(this.name);
            }
        };
        function add(a, b) {
            console.log(a, b);
            console.log(this.name);
            console.log(this);
        }
        // apply第一个参数是this,第二个参数是一个数组,数组里面是传递给函数的参数
        //会执行add的方法
        add.apply(obj, [25, 54]);
        
        // 可以利用apply与Math的方法一起使用,W3c的Math列子,有的就是利用apply来实现的
        var arr = [1, 66, 3, 55, 17, 5]
        var max = Math.max.apply(Math, arr)
        console.log(max);
        
        //直接调用Math.max()方法
        // 里面是一个字符串,如果是数组会出错NAN,所以需要用扩展运算符
        // Math.max(1, 66, 3, 55, 17, 5)
        var maxa = Math.max(...arr)
        console.log(maxa);
    </script>
</body>
</html>

bind

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>bind</title>
</head>
<body>
    <button>点击</button>
    <script>
        // bind会产生一个新的函数
        var obj = {
            name: '张三',
            age: 20,
            say: function () {
                console.log(this.name);
            }
        };
        function add(a, b) {
            console.log(a, b);
            console.log(this.name);
        }
        // bind第一个参数是this,第二个参数是一个对象,对象里面是传递给函数的参数
        // 利用bind的话,调用的函数不会立即执行
        var add1 = add.bind(obj, 25, 54);
        add1();
      
        // 不需要bind 立即调用,又想改变this指向的方式
      
      var btn=document.querySelector('button');
      
        // btn.addEventListener('click',function(){
        //     this.disabled=true;
        
        //   定时器的this指向与事件的this指向不一致
         
        //     setTimeout(function(){
        //         this.disabled=false;
        //     }.bind(this),1000);
        // });
        
        // 利用在定时器函数外部声明变量的方法去接收this
        
        btn.addEventListener('click',function(){
            this.disabled=true;
            var that=this;
            setTimeout(function(){
                that.disabled=false;
            },1000);
        });
    </script>
</body>

</html>