JS函数内this的指向以及call()、apply()、bind()改变this指向的方法

一:this指向

this的指向,是当我们调用函数时确定的,调用方式的不同 决定了this指向的不同,一般是指向函数的调用者

调用方式this指向
普通函数 调用window
构造函数调用实例对象 原型对象里面的方法也是指向实例对象
对象方法调用该方法所属对象
事件绑定方法绑定事件对象
定时器函数window
立即执行函数window
<body>
    <button>点击</button>
    <script>
        //函数的不同调用方式决定了this 的指向不同
        //1.普通函数  this指向window
        function fn() {
            console.log('普通函数的this' + this);
        }
        window.fn();
        //fn.call();
        //2.对象的方法   this指向函数调用者 也就是 对象o
        var o = {
            sayHi: function() {
                console.log('对象方法的this' + this);
            }
        }
        o.sayHi();
        //3.构造函数 this指向 s 这个实例对象  原型对象里面的this 指向 的也是 s 这个实例对象 
        function Star() {};
        Star.prototype.sing = function() {};
        var s = new Star();

        //4.绑定事件函数  this指向的是函数的调用者 btn这个对象
        var btn = document.querySelector('button');
        btn.onclick = function() {
            console.log('绑定事件函数的this:' + this);
        };
        //5.定时器函数 this指向window
        window.setInterval(function() {
            console.log('定时器函数的this:' + this);
        }, 1000); //定时器自动1s调用一次
        // 6.立即执行函数(函数)()  this指向window对象
        (function() {
            console.log('立即执行函数的this:' + this);
        })();
        //立即执行函数是自动调用的
    </script>
</body>

二:改变this指向

1.call()方法
call()方法 可以调用一个对象,简单理解为调用函数的方式,但是可以改变函数this的指向
fun.call(thisArg,arg1,arg2,…)

  • thisArg:在fun函数运行时指定this的值
  • arg1,arg2:传递的其他参数
  • 返回值就是函数的返回值,因为他就是调用函数
  • 因此我们想改变this指向,同时想调用这个函数的时候,可以使用call,比如继承
<script>
        //改变函数内this指向  js提供了三种方法 call()   apply()  bind()
        //1.call()
        var o = {
            name: 'andy'
        }

        function fn(a, b) {
            console.log(this);
            console.log(a + b);
        }
        // fn();
        // fn.call();
        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('ldh', 18, '男');
        console.log(son);
        //2.apply()
        //3.bind()
    </script>

2.apply()方法
apply()方法调用一个函数,可以调用函数以及改变函数this指向
fun.apply(thisArg,[argsArray])

  • thisArg:在fun函数运行时指定this的值
  • argsArray:传递的值,必须包含在数组
  • 返回值就是函数的返回值,因为他就是调用函数
  • 因此apply()主要跟数组有关系,比如使用Math.max()求数组最大值
 <script>
        //改变函数内this指向  js提供了三种方法 call()   apply()  bind()
        //2. apply() 应用 运用的意思
        var o = {
            name: 'andy'
        }

        function fn(arr) {
            console.log(this);
            console.log(arr); //打印的结果是字符串 不是数组    在这里注意:传入的数组里面是数字类型的得到的就是数字 传入的是字符串类型的 拿到的就是字符串
        }
        fn.apply(o, ['pink']); //此时 fn里的this就指向了o这个对象
        //1.  作用:  第一:调用函数  第二: 改变函数内部this指向
        //2. 但是参数必须是数组形式[]传递的  或者伪数组
        //3.apply 的主要应用
        //例如可以利用 apply借助于数学内置对象 求最大值
        // Math.max()
        var arr = [1, 44, 51, 95, 78];
        //var max = Math.max.apply(null, arr); //调用Math.max()函数 null:不改变this指向 arr:数组  把arr传递给Math.max()方法
        var max = Math.max.apply(Math, arr); //写成null不太好  所以我们把他写成函数的调用者 Math
        var min = Math.min.apply(Math, arr); //写成null不太好  所以我们把他写成函数的调用者 Math
        console.log(max, min); //95 1
        var max1 = Math.max(1, 2, 3);
        console.log(max1); //3
    </script>

3.bind()方法
bind()方法 不调用函数,但是能改变函数内部的this指向
fun.bind(thisArg,arg1,arg2,…)

  • thisArg:在fun函数运行时指定this的值
  • arg1,arg2:传递的其他参数
  • 返回值就是函数的返回值,因为他就是调用函数
  • 因此我们想改变this指向,但是并不像调用这个函数时,就可以使用bind()
<body>
    <button>点击</button>
    <script>
        //改变函数内this指向  js提供了三种方法 call()   apply()  bind()
        //3.  bind() 绑定 捆绑的意思
        var o = {
            name: 'andy'
        }

        function fn(a, b) {
            console.log(this);
            console.log(a + b);
        }
        //注意 bind()并不会调用函数 只是绑定 不执行!!!!!  只是改变this的指向
        //返回由指定的this值和初始化参数改造的 原函数 拷贝 
        //定义一个 f 接收返回的新函数
        var f = fn.bind(o, 1, 2); //让fn绑定了o  也就是让this指向o
        f();
        //1.不会调用原来的函数   可以改变原来的函数内部this的指向 
        //2.返回的是原函数改变this之后产生的的新函数
        //3.如果有的函数我们不需要立即调用但是又想改变这个函数内部的this指向  此时用bind
        //4.我们有一个按钮,当我们点击了之后,就禁用这个按钮,3秒之后开启这个按钮
        var btn = document.querySelector('button');
        btn.addEventListener('click', function() {
            this.disabled = true; //this指向函数调用者btn
            // var that = this; //把 btn 保存起来给that  缺点:重新开辟内存空间
            var timer = setTimeout(function() {
                    // this.disabled = false; //定时器函数里面的this指向的是window
                    //btn.disabled = false; //如果这样写的话缺点:如果var btn1 还要在这里也改成btn1 很麻烦  如果有多个按钮就不知道是谁了
                    // that.disabled = false;
                    //思路  让定时器里面的this指向btn   但是不是立即调用
                    this.disabled = false;
                    //让bind 绑定定时器的函数  注意是在函数外面绑定的  并且让定时器函数的this指向btn
                }.bind(this), 3000) //这个bind(this)中的this指向的是btn
        })
    </script>
</body>

三:call apply bind 总结

相同点:
都可以改变函数内部的this指向

不同点:

  1. call 和 apply 会调用函数,并且改变函数内部的this 指向.
  2. bind 不会调用函数,可以改变函数内部this指向
  3. call 和 apply 传递的参数不同,call传递的参数是arg1,arg2…形式 但是apply传递的参数必须是数组[arg]形式的

主要运用场景

  1. call经常做继承
  2. apply经常跟数组有关系,比如借助数学对象实现数组最大值和最小值
  3. bind不调用函数,但是还想改变this指向.比如改变定时器内部的this指向。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值