最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • JS - this 指东指西,到底指向哪里 ...

    正文概述 掘金(_人间富贵花_)   2021-03-09   535

    对于初学 JS 的同学来说,可能存在完全搞不懂 this 到底指向哪里,指东指西,指向意料之外的对象。

        —— what's fuckkkk... 你是否也有这种感觉呢?
    

    好了,我们就不要逼叨叨了, 进入主题一起来看看 this 到底指向哪里吧:

    this:被谁调用,就指向谁。

    如何理解这句话呢?我们稍稍放慢脚步,结合案例一点点进行分析:

    • 案例一:
     var a = 1;
     console.log(a)
     console.log(this.a);  // 1
     console.log(window.a) // 1
     console.log(this == window) //true
    

    案例一分析:

    1:全局执行 var a = 1, 相当于给 wiondow 对象添加了 a 属性,并赋值为 1 
    2:在全局下执行 console.log(...),此时的 this 就是指向 window 且是同一个对象
    
    • 案例二
    function test() {
      var a = 1;
      console.log(a) // 1
      console.log(this); //window
      console.log(this.a); // undefined
    }
    test();
    console.log(this.a); // undefined
    
    

    案例二分析:

    结合预编译来分析
    GO:{
    	test: function(){}
    }
    AO: {
    	a: undefined --> 1
    }
    
    在哪里调用,就指向哪里
    1:全局调用 test 函数,相当于执行了:window.test() 
    2:此时 test 函数中的 this 指向 window (在哪里调用,就指向哪里)
    3:预编译的信息可以看出,GO 中没有 a 变量 ---> undefined
    
    • 案例三:
    function test() {
       var a = 1;
     	console.log(a) // 1
     	console.log(this); //window
     	console.log(this.a); // undefined
     	function inner() {
       		console.log(this.a); // undefined
       		console.log(this); // window
     	}
     	inner();
    }
    test();
    

    案例三分析:

    结合预编译来分析
    GO:{
    	test: function(){}
    }
    AO: {
    	a: undefined --> 1
    	inner: function() {}
    }
    
    在哪里调用,就指向哪里
    1:全局调用 test 函数,相当于执行了:window.test() 
    2:此时 test 函数中的 this 指向 window
    3:预编译的信息可以看出,GO 中没有 a 变量 ---> undefined
    4:虽然在 test() 中执行 inner(), 但不要忘记了是 test() 是在全局下被调用的,因此 inner() this 指向 wiondow 
    
    • 案例四:
    var obj = {
    	names: '人间富贵花',
      	fn: function() {
       		console.log(this.names) // 人间富贵花
       		console.log(this) //  {name: '人间富贵花, fn: function(){}}
       	}
    }
    obj.fn()
    
    

    案例四分析:

    结合预编译来分析
    GO:{
    	obj: undefined ---被赋值为一个对象--> {}
    }      
    1:被谁调用就指向谁
    2: obj对象有上挂载了a 、 fn 两个属性
    3:obj.fn()执行,fn 函数中的 this 指向 obj
    
    • 案例五:(注意
    var obj = {
    	names: '人间富贵花',
      	fn: function() {
       		console.log(this.names) // 人间富贵花
       		console.log(this) //  {name: '人间富贵花, fn: function(){}}
       	}
    }
    window.obj.fn()
    
    

    很多同学看到这里就会认为:函数是在 windon 下调用的, this 为什么不指向 window 呢?

    说明: 如果一个函数中有 this , 但是他没有被上一级对象调用,那么 this 指向 window;如果被上一级对象调用,则指向上一级对象。

    案例五分析:

    1: 案例五和案例四,其实是没有任何区别的,都是在 window 下执行的
    2:为什么 window.obj.fn() 中的 this 没有指向 window 呢?
    3:函数中有 this ,但是 fn() 被上一级 obj 调用, 那么 this 指向 obj,而不会指向 window。
    

    结合案例五的分析我们可以看看以下的特殊情况了

    • 案例六:
    var obj = {
          names: "人间富贵花",
          info: {
            skill: "JavaScript",
            fn: function () {
              console.log(this); // fn 函数的上一级 info 对象 {skill: '...', fn:function(){}}
              console.log(this.names); // undefined
              console.log(this.skill); // JavaScript
            }
          }
        };
        obj.info.fn();
    

    案例六分析:

    1:obj.info.fn() 等同于 window.obj.info.fn()
    2: 被谁调用,层级比较多的情况,存在被上一级对象调用,this 指向上一级对象
    
    • 案例七:
     var obj = {
          names: "人间富贵花",
          info: {
            skill: "JavaScript",
            fn: function () {
              console.log(this); //window
              console.log(this.names); // undefined
              console.log(this.skill);// undefined
            }
          }
        };
        var test = obj.info.fn;
        test();
    
    

    哈哈 是不是又懵逼了,为什么:this.names 、this.skill 为 undefined

    案例七分析:

    1:被谁调用 this 指向谁
    2: window 下执行 test() 此时函数中的 this 指向 window
    3:window 下是没有names、skill 属性 
    
    • 案例八:构造函数
    function Person() {
       this.name = "人间富贵花";
       this.skill = "JavaScript";
       console.log(this); // Person{name: '...',skill: '...'}
     }
     var p = new Person();
     console.log(p); // Person{name: '...',skill: '...'}
    
    

    案例八分析:

    1:构造函数 this 指向 我们需要跳出:哪里调用指向哪里的思想
    2:通过 new 关键字改变了 this 的指向,将这个 this 指向了实例化后的对象 p
    
    • 案例九: call、apply
    var obj = {
        names: '人间富贵花',
        fn: function(val1, val2) {
           console.log(this.names) 
           console.log(val1 + val2) 
       }
    }
    var info = obj.fn
    info.call(obj, 1, 2)  // '人间富贵花'  3
    
    var test = {
    	names: 'RJFGH'
    }
    info.apply(test, [2, 2]) // 'RJFGH'  4
    
    

    案例九分析:

    1:info: function() {}
    2:object.call(target, val1, val2...)  object.apply(target, [val1, val2...])  
    3:call 方法改变 this 的指向,指向 obj (target),
    4:obj.names: '人间富贵花' 
    5:info.call(obj, 1, 2) ---> '人间富贵花'  3
    6:info.apply(test,[2, 2]) --->  'RJFGH'  4
    

    补充说明:构造函数 return 的问题

    function Person1() {
    	this.name = '人间富贵花'
     	console.log(this) // Person1:{...}
      	return ''
    }
    var p1 = new Person1()
    console.log(p1.name)  // 人间富贵花
    // -----------------------------------------------------------------------------
    
    function Person2() {
    	this.name = '人间富贵花'
      	console.log(this) // Person2:{...}
      	return  1
    }
    var p2 = new Person2()
    console.log(p2.name) // 人间富贵花
    // -----------------------------------------------------------------------------
    
    function Person3() {
       this.name = '人间富贵花'
       console.log(this) // Person3:{...}
     	return null
    }
    var p3 = new Person3()
    console.log(p3.name) //人间富贵花
    // -----------------------------------------------------------------------------
    
    function Person4() {
    	this.name = '人间富贵花'
     	console.log(this) // Person4:{...}
      	return []
    }
    var p4 = new Person4()
    console.log(p4.name) // undefined 
    // -----------------------------------------------------------------------------
    
    function Person5() {
       this.name = '人间富贵花'
       console.log(this) // Person5:{...}
     	return function(){}
    }
    var p5 = new Person5()
    console.log(p4.name) // undefined
    // -----------------------------------------------------------------------------
    
    function Person6() {
    	this.name = '人间富贵花'
      	console.log(this) // Person6:{...}
       	return {}
    }
    var p6 = new Person6()
    console.log(p6.name) // undefined
    

    从 Person1、Person2、Person3、Person4、Person5、Person6 例子可以看出:

    如果返回值 是一个对象,this 指向被改变且指向返回的这个对象

    如果返回值不是一个对象,this 指向不变还是指向构造函数的实例

    总结:

    • 谁调用指向谁
    • 存在对象层级调用的,被上一级调用,this 就指向上一级,否则指向 window
    • 构造函数,指向实例化的对象
    • call、apply,this 指向 target
    • 构造函数 return 的结果如果是一个对象,则会改变 this 的指向,否则不会改变指向,依旧指向实例化的对象

    起源地下载网 » JS - this 指东指西,到底指向哪里 ...

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元