JS学习笔记——JavaScript中this的指向问题(包含js中所有情况)

在js中有一个东西一直折磨的我头疼,终于下定决心好好总结一波this的各种情况。

  1. 普通函数中的this
			console.log(this);//window
			function fn(){
                console.log(this);
            }
            fn();  //window

ES5中非严格模式,普通代码全局中的this和函数中的this都指向window;
ES6中严格模式,全局中this仍然指向window,函数中this指向undefined;

  1. 对象中的this
var obj={
            a:1, 
            b:function(){
                console.log(this.a);
                //这个this只想当前对象自身obj
                //一般我们不再obj里面使用obj,因为obj中变量改变时,会发生引用改变
                //而this不会因为变量引用改变而改变,就指向当前的obj
                //console.log(obj.a)//有可能obj发生改变
            },
            c:this.a
            //这个this指向对象外this的指向,一般指window
            //对象还没有创建完成,this还没有生成,this就指向对象外this的指向
        } 
        var o=obj;
        obj={a:100,d:200};
        o.b();//1
        obj.b();//obj.b is not a function//obj指向变了
  1. 回调函数中的this:
    1. 如果直接指向的回调函数,this指向最外层window;
    2. 如果通过arguments直接使用参数指向函数,this则指向执行当前函数的arguments;
    3. 如果回调函数通过call,apply,bind重新指向了新的对象,this就是指向的这个新对象 ;
 		var obj={
            b:1,
            a:function(){
                setTimeout(function(){
                        console.log(this);
                }, 2000);//直接指向回调函数中的this,this就指向Window
                setTimeout(function(obj){
                        console.log(obj.b);
                }, 2000,this);//传入了参数obj,代替了this指向,所以这里this指向obj,打印1
            }
        }
        obj.a();

【注】只要是直接指向回调函数,不管是严格还是非严格,this就会发生改变,没有传参就会指向外面的window;

4.事件函数中this:
侦听谁,this就指向谁(只要不使用bind,不使用箭头函数)

    addEventListener在IE8中this指向window;
    addEventListenerIE8以上版本指向document

5.ES6类中的this:
(1) 普通方法中的this-------------被实例化对象
(2)静态方法static中的this-----当前类名

		class Box{
            static _instance;//单例模式
            constructor(){
                console.log(this);//普通方法中的this指向被实例化对象
            }
            play(){
                console.log(this);//普通方法中的this指向被实例化对象
            }
            static run(){
                console.log(this);
                return this;
                //静态方法中的this就是当前类名,也是构造函数constrcutor;
                //任何的静态方法中this都是当前类;
                //静态方法中无法获取到实例化对象的this;
            }
            //单例模式
            static getInstance(){
               if(!Box._instance){
                   Box._instance=new Box();
               }
               return Box._instance;
            }
            static plays(){
                this.getInstance().play();//等于Box.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.constrcutor)//true

(单例:借助于静态方法而完成实例化对象,不管在哪里调用都可以,每次调用的值也一样)
6.ES5 面向对象中的this

		function Box(){
            console.log(this);
        }
        //这种就相当于ES6中实例化对象,Box.prototype.play就是ES6的b.play()
        Box.prototype.play=function(){
            console.log(this);//this是指向执行该方法的实例化对象
        }
        //这种就相当于ES6中的静态方法static
        //Box是对象,对象下的方法中的this指的就是该对象
        Box.run=function(){
           console.log(this);//Box
        }
        
        Box();//this是window或者undefined
        var b=new Box();//this是实例化后的b对象
        b.play();

7.箭头函数中this:this是上下文环境中this的指向(箭头函数外this的指向)
情况一:

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

情况二:

		var obj={
             a:function(){
                 document.addEventListener("click",this.clicHandler);
             },
             clicHandler:function(e){
                 setTimeout(()=>{
                     console.log(this);
                 },2000);
             }
         }
         obj.a();//#document

情况三:

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

情况四:

		function Box(){}
        //类似于ES6中的静态
        Box.prototype.run=()=>{
            console.log(this); //window
        }
        var b=new Box();
        b.run(); 

8.call apply bind中的this:

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

(特殊情况)

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

以上这8种情况大概就是js中this指向的大部分情况,如果有其他情况,随时欢迎共同交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值