深刻理解javaScript系列:各类上下文中的this

1.this关键字在何处出现?javascript

  this他只能出如今函数中。固然在全局做用域中是个例外,意思是this只可能在两种情境下出现,一个是在函数体内,另外一个是在全局做用域。java

2.this是什么?数组

  this是关键字,语言规范里规定他指向函数执行时的当前对象。它表明函数运行时,自动生成的一个内部对象,只能在函数内部使用。浏览器

3.this到底指向哪?app

  首先明确this在JavaScript中和函数的执行环境而不是声明环境相关。函数

  第一条中已经说过,this只能出如今函数中和全局做用域中,全局做用域中this指向全局对象(全局对象在浏览器这个环境中指window)。this

  若是this出如今函数中,那就要分状况来看this到底指向哪了。指向的依据就是函数的执行环境而不是声明环境。其实能够以一句话来归纳就是this永远指向所在函数的全部者,当没有显示的全部者的时候,那么this指向全局对象。spa

4.各类状况下的this的具体指向?prototype

  (1).全局做用域code

1
console.log( this )

  直接在全局做用域中打印this,其指向为window。

  因此在全局做用域中this指向全局对象。

  (2).函数做为某个对象的成员方法调用

1
2
3
4
5
6
7
8
var  name =  "chirenmiao1" ;
var  obj= {
     name:  "chirenmiao2" ,
     getName:  function  () {
         console.log( this .name);
     }
}
obj.getName(); //chirenmiao2

  

  在全局做用域中声明全局变量name,在obj对象中声明同时也声明一个name。当用对象obj调用他的成员方法getName的时候,this指向这个obj,所以打印出来的this.name为obj的name。

  因此函数做为某个对象的成员方法调用时this指向该对象。

  (3).函数做为函数直接使用

1
2
3
4
5
6
7
8
9
var  name =  "chirenmiao1" ;
var  obj= {
     name:  "chirenmiao2" ,
     getName:  function  () {
         console.log( this .name);
     }
}
var  getName= obj.getName;
getName();    //chirenmiao1

  一样的仍是上边的一段代码,只不过此次咱们把getName这个函数直接执行,这时在函数执行的时候他没有明确的当前对象,因此默认这时this就指向了全局对象。

  因此函数做为函数直接使用时this指向全局对象。

  

1
2
3
4
function  myFun() {
     console.log( this );
}
myFun();

  还有就是函数声明直接执行的时候,this也指向全局对象。

  其实上边三条就已经简单覆盖了this指向的全部状况,下面紧接着讲述一些稍微特殊的状况。

  (4).函数做为构造函数调用

1
2
3
4
5
6
7
8
9
var  name =  'chirenmiao1' ;
var  Obj =  function  (x, y) {
     this .name =  'chirenmiao2' ;
}
Obj.prototype.getName =  function  () {
     console.log( this .name);
}
var  myObj =  new  Obj();
myObj.getName(); //chirenmiao2

  函数做为构造函数调用时this指向用该构造函数构造出来的新对象。

  (5).setTimeout和setInterval以及匿名函数

1
2
3
4
5
6
7
8
9
10
11
var  name =  "chirenmiao1" ;
var  obj = {
     name:  "chirenmiao2" ,
     getName:  function  () {
         setTimeout( function  () {
             console.log( this .name);
         }, 1000);
     },
};
 
obj.getName(); //chirenmiao1

  这两个函数执行的时候第一个参数能够为一个匿名函数,也能够是一个声明好的函数引用,因此this指向也就是指这个匿名函数或者函数引用的this的指向。经过第一条已经知道匿名函数或者在全局做用域中声明的函数直接执行的时候,其中的this指向全局对象,因此在这里也同样,setTimeout和setInterval二者运行时,this指向全局对象。

  这个时候若是还想输出的是chirenmiao2,也就是this指向obj的话就须要作点手脚了。

1
2
3
4
5
6
7
8
9
10
11
12
var  name =  "chirenmiao1" ;
var  obj = {
     name:  "chirenmiao2" ,
     getName:  function  () {
         var  self =  this ;
         setTimeout( function  () {
             console.log(self.name);
         }, 1000);
     },
};
 
obj.getName(); //chirenmiao2

  固然这样是改变不了this指向的,可是能够经过把this赋值给self,就实现了保存this指向的做用。

  紧接着是匿名函数。

1
2
3
( function  () {
     console.log( this );
})() //window

  匿名函数中的this指向全局对象,由于他没有显示的全部者。

  (6)apply、call、bind

  这三个函数是函数对象的一个方法,他们的做用就是为了改变函数执行时候的this指向,具体用法以下:

  call:call(obj[,arg1][,arg2]);第一个参数为强制改变须要指向的对象,后边可选的是该函数的参数,若是不传obj的话默认为window。

  apply:apply(obj[,arr]);第一个参数为强制改变须要指向的对象,后边可选的是该参数集合的数组形式,若是不传obj的话默认为window。

  apply和call的做用和调用形式基本一致,不一样的是call后面的参数与方法中是一一对应的,而apply的第二个参数是一个数组,数组中的元素是和方法中一一对应的,这就是二者最大的区别。二者均可以不传参数,此时默认改变指向的对象为全局对象。

  bind:bind的调用形式和call相同,可是他返回的是改变调用对象后的函数引用,因此还要再执行一次,也就是obj.fun().bind()()。

总结:this做为函数运行时,自动生成的一个内部对象,只能在函数内部使用。具体this指向谁,要看this的全部函数是谁调用的,具体状况可分为全局做用域、做为某对象的方法调用、直接执行、匿名函数直接执行、call、apply、bind强制改变调用对象等。

相关文章
相关标签/搜索