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
posted @ 2018-09-02 15:17  爱学习的前端工程师  阅读(186)  评论(0编辑  收藏  举报