JS中this指向问题

JS中的this指向一直扰乱着我们,很多时候觉得自己写的东西没有bug但是执行后的结构总是跟自己预想的不一样,这个时候我们就该想想是不是我们的对象的this出现了问题。接下来我们一步一步地分析一下this的问题。

1.非箭头函数中this在函数定义的时候是确定不了的,只有在函数执行的时候才能确定this到底指向谁,this指向最终调用它的对象

在js中this主要分为以下几种情况

  1. 在全局作用域下
    var name = "Eric"
    console.log(this) //输出window
    console.log(this.name)//输出"Eric"

    非严格模式全局作用域下this永远指向window,如果是严格模式,this是undefined

  2. 在函数作用域下

    var name = "Eric"
    function show(){
        console.log(this);//输出window
        console.log(this.name);//输出"Eric"
    }
    show();

    此种情况下show()调用的时候我们可以看做window.show(),show()的执行环境是window,也就相当于函数show()被window调用所以this指向window。但是在严格模式下this依然是undefined

  3. 在对象里面

    var obj = {
        name : "Eric";
        show:function(){
            console.log(this);
            console.log(this.name);
        }
    }
    obj.show()
    //obj
    //"Eric"

    此情况下函数show()是通过obj这个对象调用的,所以函数show()里面的this指向obj.这里有个经典的问题,如下:

    var obj = {
        show:function(){
            console.log(this);
            function fn(){
                console.log(this);
            }
            fn();
        }
    }
    obj.show()
    //obj
    //window
    /*此时fn()里 的this会指向window....完了,看懵了,为什么这个this会指向window呢?因为fn()在show()函数中,但是并没用通过obj或者show直接调用,只是自己调用,因此,fn()就是一个全局函数,所以fn()中的this会指向window*/

    为了彻底理解这个this我们再举个例子

    var obj = {
        name : "Eric",
        show:function(){
            console.log(this);
        }
    }
    var outer = obj.show;
    outer()//window

    这里的this指向window.这是因为将obj里面的show赋值给outer的时候并没有执行,只是吧obj里面的函数show给了outer,而outer是在window里创建的相当于

    var outer = function(){
       console.log(this)
    }
    outer()//window

    这就和第二种情况一样了,outer是通过window直接调用的,所以this指向window,还有一种情况

    var obj = {
        name : "Eric",
        show:function(){
            console.log(this);
            return function(){
                console.log(this)    
            }
        }
    }
    obj.show()()
    //obj
    //window

    这种情况函数show()里面返回了一个匿名函数,在函数show()里面并没有调用,只是定义,真正的调用时在window下调用的,写两个括号可能不太清楚,我们可以这样写var outer = obj.show();这里只执行了show里面的console.log并没有执行返回的匿名函数,outer()这样才是表示window下调用,所以第二个this指向window
    同理想setTimeout这种函数如下

    var obj = {
        name:"Eric",
        show:function(){
            console.log(this)
            setTimeout(function(){
                console.log(this)
            },1000)
        }
    }
    obj.show()
    //obj
    //window

    setTimeout中的function我们可以理解为是一个callback,即:

    function callback(){}
    setTimeout(callback,1000)

    它的伪代码可以这样写

    function setTimeout(fn,delay) {
    // 等待delay 毫秒
    fn(); // <-- 调用位置!
    }

    他是直接调用fn(),前面没有给任何对象绑定在一起,所以根据JavaScript的规则,它属于默认绑定,自然就是window了

  4. 构造函数中的this,我们先来看例子

    function Object(){
        this.name = 12;
        this.show= function(){
            console.log(this) //Object:{a:12,show:f()}
        }
    }
    var obj = new Object()
    obj.show()//obj

    (1) 要明白构造函数的this指向,我们需要明白调用构造函数经历的步骤:

      a。创建一个新对象。

      b。将构造函数的作用域赋给新对象(因此this就指向了这个新对象)。

      c。执行构造函数中的代码(为这个新对象添加属性)。

      d。返回新对象。

  5. 箭头函数中的this
    箭头函数的this是在定义函数时绑定的,不是在执行过程中绑定的。简单的说,函数在定义时,this就继承了定义函数的对象。
     

    var obj = {
        fun1:function(){
            console.log(this)
        },
        fun2:function(){
           console.log(this)
           setTimeout(function(){
                console.log(this)
           },1000)
        },
        fun3:function(){
            console.log(this)
            setTimeout(()=>{
                console.log(this)
            },1000)
        }
    }
    obj.fun1()//obj
    obj.fun2()//obj window
    obj.fun3()//obj obj

    通过fun2和fun3的对比我们发现箭头函数的this是和和他上一级函数的this保持一致的,箭头函数中是没有this的,所谓的箭头函数的this是通过继承来的,继承的就是它上一级的函数中的this

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值