JavaScript函数调用和不同函数(apply,bind,call)的this指向问题。

函数定义方式

  1. 所有函数都Function的实例对象。
  2. 函数也属于对象
  3. 指向:表示这个函数是谁的属性。调用函数得人是谁。函数指向window就是,window调用这个函数。

三种方式

    <script>
        //1.自定义函数
        function f(){};
        //2.函数表达式(匿名函数)
        var fun=function(){};
        //3.利用new Function('参数1','参数2',函数体);
        //执行效率低
        var f=new Function('a','b','console.log(a+b)');
        f(1,2);
    </script>

在这里插入图片描述

函数的调用

    <script>
        //1.普通函数
        function f(){
            console.log('人生巅峰');
        }
        fn.call(); fn();
        //2.对象的方法
        var o{
            say:function();{
                console.log('人生巅峰');
            }
        }
        o.say();
        //3.构造函数
        function Star(){};
        new Star();
        //4.绑定事件函数
        btn.onclick=function(){};
        //5.定时器函数
        setInterval(function(){},1000);//定时器一秒钟调用一次。
        //6.立即执行函数
        (function(){
            console.log('人生巅峰');
        })();
        //立即执行,自动调用。
    </script>

不同函数的this指向问题

  • 指向:表示这个函数是谁的属性。调用函数得人是谁。
  • 如window调用this,那么就是this指向window。
    <script>
        //1.普通函数this指向window
        function f(){
            console.log('人生巅峰');
        }
        window.fn();

        //2.对象的方法this指向o
        var o{
            say:function();{
                console.log('人生巅峰');
            }
        }
        o.say();

        //3.构造函数this指向ldh这个实例对象
        //原型对象里的this指向的也是ldh对象实例
        function Star(){};
        new Star();
        Star.prototype.sing(){}
        var ldh=new Star();

        //4.绑定事件函数。this指向函数调用者,也就是btn
        btn.onclick=function(){};

        //5.定时器函数。this指向window。
        //函数调用者是window
        setInterval(function(){},1000);

        //6.立即执行函数
        //指向的是window
        (function(){
            console.log('人生巅峰');
        })();
        //立即执行,自动调用。
    </script>

可以改变函数内部this指向不同对象

call()

  • call是一个可以调用函数 第二个可以改变函数内this指向
  • call主要作用可以实现继承
    <script>
        //1.call()
        var o={
            name:'andy'
        }
        function f(){
            console.log(this);
        };       
        //由window改成0
        f.call(o);
        
        //2.实现继承
        function father(name,age){
            this.name=name;
            this.age=age;
        }
        function son(name,age){
            //改变指向
            //调用父类构造方法,传递儿子的值。
            father.call(this,name,age);
        }
        var son=new son('lll',19);
    </script>

apply

apply()方法调用一个函数。简单理解为调用函数方式,但是他可以改变this指向。

fun.apply(thisArg,[argsArray])

  • thisArg:在fun函数运行时指定this的值。
  • argsArray:传递的值,必须包含在数组里面
  • 返回值就是函数的返回值,因为它就是调用函数
    <script>
        //2.apply()
        var o={
            name:'andy'
        }
        function f(){
            console.log(this);
            //打印的不是数组形式,是字符串形式。
            console.log(arr);
        };  
        //1.调用函数,改变函数内部this指向     
        //2.必须是数组形式
        //3.apply主要作用 用apply借助于数学内置对象最大值。
        //Math.max();
        var arr=[1,66,3,99,4];
        var max=Math.max.apply(null,arr);
        //尽量不用null。理解为自己调用自己
        var max=Math.max.apply(Math,arr);
        f.apply(o,['pink']);
    </script>`在这里插入代码片`

bind

类似于绑定到某一新函数身上,不会调用原函数。

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

  • thisArg:在函数运行时指定的this值。
  • arg1,arg2:传递的其他参数
  • 返回由指定的this值和初始化参数改造的原函数的拷贝

我们有一个按钮,当我们点击之后,就禁用这个按钮,3秒钟之后开启这个按钮。

  1. 时间函数指向的btn按钮。定时器函数this指向的是window
  2. bind里this指向btn这个对象,因为在function括号外面
  3. 定时器不需要立刻执行,但又需要this指向btn
<body>
    <button>点击</button>
    <script>
        //3.bind()
        var o={
            name:'andy'
        }
        function f(a,b){
            console.log(this);
            console.log(a+b);
        };  
        //只是绑定,并不执行
        var f2=f.bind(o,1,2);
        f2();
        //1.不会调用原来函数 可以改变原来函数内部this指向
        //2.返回的是原函数改变this之后的新函数
        //3.我们有一个按钮,当我们点击之后,就禁用这个按钮,3秒钟之后开启这个按钮。
        var btn=document.querySelector('button');
        btn.onclick=function(){
            this.disabled=true;//时间函数指向的btn按钮
            var that=this;
            setTimeout(function(){
                that.disabled=false;//定时器函数this指向的是window
            },3000)
        }
 //====================================================================
            var btn=document.querySelector('button');
            btn.onclick=function(){
            this.disabled=true;//时间函数指向的btn按钮
            setTimeout(function(){
                this.disabled=false;//定时器函数this指向的是window
            }.bind(this),3000)
        }//bind里this指向btn这个对象,因为在function括号外面
        //定时器不需要立刻执行,但又需要this指向btn
    </script>
</body>

适用于:有的函数不需要立刻调用,但是又想改变内部的this指向。

总结

相同点:

  1. 都可以改变函数内部this指向

不同点:

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

主要应用场景:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值