JavaScript中的this指向详解

  • //"use strict"
    console.log(this)
    function fn(){
        console.log(this)
    }
    //ES5非严格模式 全局中this和函数中this都指向window
    //ES5严格模式, ES6,全局中this仍然指向window,函数中的this指向 undefined
    
  • var obj = {
        a:1,
        b:function(){
            console.log(this.a);//this指向当前对象自身obj,
            //this不会因为变量引用改变而改变
            //为什么不用console.log(obj.a);是因为obj变量会发生引用改变
        },
        c:this.a;//this指向对象外this的指向,在这里是undefined
        //为什么指向对象外this指向,在创建对象的时候,这个对象还没有创建完成的时候,this还没有生成,this就指向对象外this指向
    }
    
  • //回调函数中的this
    var obj = {
        a:function (){
            console.log(this,"________________")//obj
            var self = this;
            function fn1(fn){
                console.log(this);//window  直接执行的函数this指向window
                //fn();
                //arguments[0]();
                //fn.call(this);
                //fn.call(self)
            }
    
            function fn2(){
                console.log(this);//window       
                console.log(this);//Arguments
                console.log(this);//window
                console.log(this);//obj
            }
            fn1(fn2)
      }
    }
    obj.a()
    //回调函数中
    //1、如果直接执行的回调函数,this指向最外层window(回调执行时,不知道所在范围的原本this指向,这时候this指向window)
    //2、如果通过arguments直接使用参数执行函数,this则指向执行当前函数的arguments
    //3、如果回调函数通过call,apply,bind重新指向了新的对象时,this就是指向的新对象
    
  • "use strict"
    var obj = {
        b:1,
        a:function(){
            setTimeout(function(){
                console.log(this);//回调函数永远指向window,即使开启严格模式
            }, 2000);
        }
        
        a:function(){
            setTimeout(function(obj){
                console.log(obj.b)
            }2000,this)
        }
    }
    obj.a();
    
  • //事件中的this,只要不是用bind,只要不使用箭头函数,那就一定是事件侦听对象
    var obj = {
        a:function(){
            //特殊的回调函数
            document.addEventListener("click",this.clickHandler);
    		//兼容IE
            document.attachEvent("onclick",this.clickHandler);
        },
        clickHandler:function(e){
            console.log(this);//addEventListener事件侦听的对象,e.currentTarget
            console.log(this);//IE8 attachEvent侦听事件时,this指向window
        }
    }
    obj.a()
    
  • //ES6类
    class Box{
        constructor(){
            console.log(this);//指向被实例化的对象
        }
        play(){
            console.log(this);//指向被实例化的对象
        }
        static run(){
            console.log(this);//静态方法中,this时当前类名,也是构造函数
            console.log(this === Box);//true
            //任何的静态方法中this都是当前类
            //静态方法中无法获取到实例化对象的this的
            return this;
        }
    }
    
    var b = new Box();//会执行构造函数,这时构造函数中的this就是这个b对象
    b.play();//执行b对象下的方法play,因此play方法中this被指向b。也就是说谁执行play,this指向谁
    
  • //单例模式
    //静态方法中无法获取到实例化对象的this的,可以曲线获取
    class Box{
        static _instance
        constructor(){   
        }
        static getInstance(){
            if(!Box._instance) {
                Box._instance = new Box()
            }
            return Box._instance;
        }
        play(){
            console.log(this)
        }
        static plays(){
            //this.getInstance().play();
            //在执行getInstance();时,永远都只能获取这唯一的一个实例化对象,
            //所以叫做单例,单例的的特征是借助静态方法可以在任何位置调用,而完成实例化方法的特征
            var o = this.getInstance();
            var o1 = this.getInstance();
            console.log(o === o1);//true
        }
    }
    
  • //ES5面向对象中的this
    function Box(){
        console.log(this);
    }
    Box.prototype.play = function(){
        console.log(this);//this是执行该方法的实例化对象
    }
    Box.run = function(){
        console.log(this);//this指向Box
    }
    Box();//this是window或者undefined
    var b = new Box();//this是实例化后b对象
    b.play();
    
  • //箭头函数
    setTimeout(()=>{
        console.log(this);//this 指向window, 
        //this是箭头函数外this的指向
    },2000)
    
    
    var obj = {
            a:function (){
                setTimeout(()=>{
                    console.log(this)//obj,this是箭头函数外this的指向
                    //上下文环境中this的指向
                },2000)
            }
        }
    obj.a()
    //-----------------------------------------------------------
    var obj = {
        a:function(){
            document.addEventListener("click", clickHandler);
        },
        clickHandler(){
            setTimeout(()=>{
                console.log(this);//this指向document
            },1000)
        }
    }
    //-----------------------------------------------------------
    var obj = {
        a:function(){
            console.log(this);//obj
        },
        b:()=>{
            console.log(this);//window
        }
    }
    //------------------------------------------------------
    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();//fn中this指向window或者undefined 
    fn.call(obj);//fn中this指向obj
    fn.apply(obj);//fn中this指向obj
    fn.bind(obj);//fn中this指向obj
    
  • var obj = {
        a:function(){
            console.log(this);//如果使用call apply bind带入的是null将会把这里的this重新指向window
        }
    }
    obj.a.call(null)
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值