zoukankan      html  css  js  c++  java
  • 关于this的指向问题

    概要

    在javascript当中每一个function都是一个对象,this是javascript语言的一个关键字。它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用
     
    this出现的场景分为四类
    1、有对象就指向调用对象
    2、没调用对象就指向全局对象:window是js中的全局对象
    3、用new构造就指向新对象
    4、通过apply或者call或bind来改变this的指向
     
     
    1、函数有所有对象时:指向所属对象
     
    举个栗子
     
    var a={value:20};
    a.show=function(){
         console.log(this.value)
         console.log(this)
    }
    show()这个函数所属对象是a,并由a调用.因此this指向对象是a
     
    函数没有所属对象:指向全局对象
     
    window.name='阿姨请您别把你闺女介绍给我';
    function foo(){
         console.log(this.name)
    }
    foo()
     
    构造器中的this:指向新对象
     
    var a=function(){
         this.value=100;
    }
     
    var p1=new a();
    console.log(p1.value);//100
     
    这里面的this指向新对象
     
    apply和call调用以及bind绑定:指向绑定对象
     
    apply()方法接受两个参数第一个是函数运行的作用于,另一个是一个参数数组(arguments)
    call()方法第一个参数的意思与apply方法相同,只是其他的参数需要一个个列举出来
    简单来说:call的方式更接近我们平时调用函数,而apply需要我们传递Array形式的数组给它。
     
    var a={value:100};
    var show=function(){
         console.log(this)
    }
     
    foo();//全局变了 global
    foo.apply(a);//{value:100}
    foo.call(a);//{value:100}
     
    var aA=foo.bind(a);
    aA();//{value}
     
     
     
     
     
    关于this的指向
     
    this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向是那个调用它的对象
     
    栗子一:
     
    function a(){
         var user='阿姨请不要把您闺女介绍给我';
         console.log(this.user);//undefined
         console.log(this);//window
    }
    按照我们上面说的this最终指向的是调用它的对象,这里的函数a实际是被window对象所点出来的,下面代码可以证明
     
    function a(){
         var user='阿姨请不要把您闺女介绍给我';
         console.log(this.user);//undefined
         console.log(this);//window
    }
    window.a();
     
    栗子二:
     
    var a={
         user:'阿姨请不要把您闺女介绍给我',
         fn:function(){
             console.log(this.user) 
         }
    }
    a.fn()
     
    这里面的this指的是a,因为你调用这个fn是通过a.fn()执行的,那自然指向就是对象a,this的指向在函数创建的时候是觉定不了的,在调用的时候才能决定
     
    栗子三:推翻上面的理论
     
    var a={
         user:'阿姨请您不要把您闺女介绍给我'
         foo:function(){
              console.log(this.user)
         }
    }
    window.a.foo();//输出来是a这个对象里面的user。
     
     
     
    为什么不是window呢?按照道理来说this会指向调用它的对象,window是js中的全局对象,而我们创建变量其实是给window添加属性,所以我们可以用window.a
     
     
    我们在来看一个栗子
     
    var a={
         b:10,
         foo:{
              b:20,
        show:function(){
             console.log(this)
         }   
         }
    }
    a.foo.show()
     
    这里面输出的是foo这个对象,为什么会是foo?而不是a!那么下面我们来说一下this的几种情况
    1、如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版中this指向的不是window,但是我们不讨论严格模式
    2、如果一个函数中有this,这个函数有被上一级对象调用,那么this指向的就是上一级的对象
    3、如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象。上面的例子可以证明
     
    栗子四:继续探讨第三种情况
     
    var a={
         b:10,
         foo:{
              show:function(){
                  console.log(this.b) 
              }
         }
    }
    a.foo.show()//undefined
    尽管对象foo中没有a这个属性,这个this指向的也是对象foo,因此this只会指向它的上一级对象,不管这个对象中有没有this要的东西
     
    栗子五:特殊情况
     
    var a={
         b:10,
         foo:{
              b:20,
              show:function(){
                   console.log(this.b);
                   console.log(this)
              }
         }
    }
     
    var j=a.foo.show;
    j()
    //第一次输出是undefined
    //第二次输出的是window
     
    这里的this指向是window,为什么会这样?我们要清楚一句话this永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,上面的案例中show被foo引用,但是在将show赋值给变了j的时候并没有执行,所以最终指向是window
  • 相关阅读:
    Python爬虫连载1-urllib.request和chardet包使用方式
    Java连载69-接受输入、用数组模拟栈
    HTML连载61-焦点图、固定定位
    Java连载68-数组的拷贝、二维数组
    [Java] MVC
    [Java] JSP
    [Java] HTTP
    [设计模式] 设计模式课程(八)--抽象工厂模式
    [设计模式] 设计模式课程(七)--工厂模式
    [刷题] 75 Sort Colors
  • 原文地址:https://www.cnblogs.com/junjun-001/p/11754662.html
Copyright © 2011-2022 走看看