Fork me on GitHub

JS this的指向

JS中 this 在各个环境下的指向问题!

 

  一:this在普通函数中的指向 --> window

1 // 普通函数中的this指向 ----> window
2 function fn(){
3     console.log(this) // ES5 this ----> window
4     console.log(this) // ES6 this----> undefined
5 }

  当我们在js脚本中定义一个函数,这个函数当调用时他的指向为window,之所以为window是因为在ES5中定义变量和函数都存在变量提升,所以我们的函数和变量都是挂在 window下,在调用函数时,我们通常都会省略window,直接使用函数,所以调用函数其实是window.fn,所以this的指向为它的上文就是window,那么在ES6中出现了新的特性和规定,将不再存在变量提升,所以在ES6的普通函数中this的指向为undefined。

  二:this在回调函数中的指向(不包含事件处理回调函数)- window

 1 var obj = {
 2 
 3     a:function(fn){
 4         // 将obj下的 c 方法带入obj下 a 方法中,执行,完成回调
 5         fn()
 6     },
 7     b:function(){
 8         var arr = [1,2,3,4]
 9         arr.forEach(function(){
10             // 在数组方法 foreach 的回调函数中,this的指向为window
11             console.log(this)  // this --> window
12         })
13 
14         // 定时器的回调函数中,this的指向为window
15         setTimeout(function(){
16             console.log(this)  // this --> window
17         },1000)
18     },
19     c:function(){
20         // 此回调函数的this为window
21         console.log(this) // this --> window 
22     }
23 }
24 // 将obj下的 c 方法带入obj下 a 方法中
25 obj.a(obj.c)

  在以上的案例我们可以发现,在回调函数中this的指向都是window,尽管它处在一个对象的环境中,主要原因是回调函数的指向默认为window,且回调函数并没有对象去调用

  三:this在事件处理函数中的指向   --> 监听事件对象本身

 1 document.addEventListener("click",clickHandler)
 2 function clickHandler(){
 3     console.log(this) // this --> document
 4 }
 5 var obj0={
 6     a:function(){
 7         document.addEventListener("click",this.clickHandler)
 8     },
 9     clickHandler:function(){
10         console.log(this) // this --> document
11     }
12 }

在如上的案例中,分别给document在两个环境下监听click事件,都是指向事件对象本身,事件的this指向是最好辨别的,只需要记住事件对象是谁就可以。

  四:对象方法中的this指向  --> 就是调用方法的对象本身

1 var a = 20
2 var obj1 = {
3     a:1,
4     b:this.a,   // b:20 - this的指向为 全局的a=20
5     c:function(){
6         console.log(this) // 这里this的指向为对象 obj1本身
7     }
8 }
9 obj1.c()

在对象中:对象的属性如果使用this,那么this的指向为对象外部的this,对象的方法使用this,调用这个方法的对象就是为this的指向。

   五:ES6 类中的this指向 --> 实例化对象

 1 class Box{
 2     a = 1
 3     static a = 3
 4     // 静态属性的this只会去指向相对应的静态属性,不会指向动态方法
 5     // 所以c = 3
 6     // 当 静态属性 a 没有时,c = undefined
 7     static c = this.a  // c = 3
 8     b = this.a
 9     constructor(){
10         console.log(this)  // this --->实例化对象
11     }
12     play(){
13         console.log(this)  // 谁执行 pily方法this就指向谁
14         document.addEventListener("click",this.clickFunction)
15     }
16     clickFunction(e){
17         console.log(this)
18     }
19 }
20 // 实例化对象 - box
21 var box = new Box()

在ES6 的类中,有两种方法:

一:静态方法:就是在属性或者方法的前面写上 static ,静态方法的this指向为 类本身,不管是属性还是方法

二:动态方法:没有使用 static的都是动态方法,通过构造函数 new出来调用,动态方法的this指向就是谁调用这个方法this指向就是谁,就是实例化对象  

  六:箭头函数的this指向 -->为箭头函数外部的this

 1 var obj3 = {
 2     a:()=>{
 3         console.log(this)  // this指向 ---> window
 4     }
 5 }
 6 obj3.a()
 7 
 8 var obj4 = {
 9     a:function(){
10         var o = {
11             b:()=>{
12                 console.log(this)  // this指向 ---> obj4
13             }
14         }
15         o.b()
16     }
17 }
18 obj4.a()

这个案例中通过2个对象来验证箭头函数改变this的指向,在对象中调用方法那么this指向为该对象,当通过使用箭头函数后,this将当前this的指向全部指向外部,那么obj3.a的this指向本为obj3,遇到箭头函数后,this就指向obj3的外部,为window。同样在obj4也是一样的道理!

posted @ 2020-07-11 17:21  Dm码羊  阅读(63)  评论(0编辑  收藏