关于JavaScript中万恶的this

什么是this?

定义:this是包含它的函数作为方法被调用时所属的对象。
说明:这句话有点咬嘴,但一个多余的字也没有,定义非常准确,我们可以分3部分来理解它!
1、包含它的函数。2、作为方法被调用时。3、所属的对象。

严格模式this的指向

"use strict";
        console.log(this);//指向的window
        function fn(){
            console.log(this);//undefined
        }
        fn();

ES5非严格模式 全局中this和函数中this都指向window
ES5严格模式,ES6,全局中this仍然指向window,函数中this指向undefined

对象模式this的指向

var obj={
            a:1,
            b:function(){
            console.log(this);//this不会因为变量引用改变而改变
            this指向当前对象自身obj
            console.log(obj.a);//变量会发生引用改变
            },
            c:this.a
            // this指向对象外this的指向
            // 对象没有创建完成时,this还没有生成,this就指向对象外this的指向
        }

        var o=obj;
        obj={a:10,d:10}

        o.b(); 

回调函数this的指向

var obj = {
        a: function () {
            console.log(this,"____");
            var self=this;
            function fn1(fn) {
              fn();
              arguments[0]();
                fn.call(self);
            }
            function fn2() {
                console.log(this);//window 回调函数中
                // 1、如果直接指向的回调函数,this指向最外层window
                // 2、如果通过arguments直接使用参数指向函数,this则指向执行当前函数的arguments
                // 3、如果回调函数通过call,apply,bind重新指向了新的对象时,this就是指向新对象
            }
            fn1(fn2);
        },
      };

      obj.a();

     var obj={
          b:1,
          a:function(){
             setTimeout(function(){
                    console.log(this);
              }, 2000);
            setTimeout(function(obj){
                   console.log(obj.b);
              }, 2000,this);
          }
      }
      obj.a();

事件中this的指向

var obj={
          b:1,
          a:function(){
            //   特殊的回调函数
              document.addEventListener("click",this.clickHandler);
          },
          clickHandler:function(e){
                console.log(this);//事件侦听的对象 e.currentTarget
          } 
      } 

       var obj={
          b:1,
          a:function(){
          console.log(this);
            //   特殊的回调函数
            document.addEventListener("click",this.clickHandler);
           document.attachEvent("onclick",this.clickHandler);
          },
          clickHandler:function(e){
          console.log(this===document);//addEventListener事件侦听的对象 e.currentTarget
          console.log(this===window);//IE8 attachEvent侦听事件时,this指向window
          } 
      } 
      obj.a();

ES6类中的this

class Box{
     static _instance;
      constructor(){
     console.log(this);//指向被实例化的对象
      }
      static getInstance(){
      		   if(!Box._instance){
               Box._instance=new Box();
              }
               return Box._instance;
           }
           play(){
               console.log(this,"|");//指向被实例化的对象
           }
           static run(){
                console.log(this);
              console.log(this===Box,"____");
              // this就是当前类名也是构造函数
               // 任何的静态方法中this都是当前类
               // 静态方法中无法获取到实例化对象的this的
               return this;
           }

          static plays(){
               this.getInstance().play();
              var o=this.getInstance();
               var o1=this.getInstance();
               console.log(o===o1);
           }
      }

      var b=new Box();//会执行构造函数,这是构造函数中this就是这个b对象
       b.play();//b对象下的方法play,因此play方法中this被指向b,谁执行play,this指向谁
       console.log(Box.run()===b);//false
       console.log(Box.run()===b.constructor);//true

       Box.plays();

ES5 面向对象中的this

function Box(){
         console.log(this);
       }
       Box.prototype.play=function(){
           console.log(this);//this是指向执行该方法的实例化对象
       }

       Box.run=function(){
           console.log(this);//Box
       }

       Box();//this是window或者undefined
       var b=new Box();// this是实例化后b对象
      b.play();

箭头函数中的this

var obj = {
         a: function () {
           setTimeout(() => {
             console.log(this);//this是箭头函数外this的指向
             // 上下文环境中this的指向
           }, 2000);
         },
       };
       obj.a();
         var obj={
             a:function(){
                 document.addEventListener("click",this.clicHandler);
             },
             clicHandler:function(e){
                 setTimeout(()=>{
                     console.log(this);
                 },2000);
             }
         }
         obj.a();


         var obj={
             a:function(){
                 console.log(this);//obj
             },
             b:()=>{
                console.log(this);//window
             }
         }
         obj.a();
         obj.b();
        function Box(){

        }
        Box.prototype.run=()=>{
            console.log(this);//window
        }

        var b=new Box();
        b.run();


     call apply bind
     function fn(){
        console.log(this);
     }
     var obj={a:1}
     fn.call(obj);//fn中this指向obj
     fn.apply(obj);//fn中this 指向obj
    fn.bind(obj)();//fn中this指向obj

        var obj={
             a:function(){
         function fn(){
             console.log(this);
         }
                 fn();
                 console.log(this);//window 如果是call apply bind 带入的是null,将会把这里的this重新指向window
             }
         }
        obj.a.call(null);
             class Box{
            constructor(){

            }
            play(){
                var o={
                    run:function(){
                        function fns(){
                            console.log(this);
                        }
                        return fns;
                    },
                    play:function(fn){
                        fn();
                         arguments[0]();
                    },
                    clickHandler(){
                        // this   实例化的b
                       o.play.call(this,o.run());
                    }
                }
                document.addEventListener("click",o.clickHandler.bind(this));
            }
        }
        
        var b=new Box();
        b.play(); 
         var obj={
             a:10,
             abc:function(){
                 setTimeout(()=>{
                     this.a++;
                     console.log(this.a,"_______");
                    (function(){
                         this.a++;
                         console.log(this.a);
                     }).call(this.c)
                 },1000);
             },
            c:{
               a:20
           }
         }

        obj.abc();

PS:如果想获取更多的知识视频,加QQ好友10398975免费送给大家

  • 12
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值