js中this的指向问题总结(精华版)

js中this的指向问题总结

1.全局的this和普通函数中的this

  • ES5非严格模式 全局中this和普通函数中this都指向window
  • ES5严格模式,ES6,全局中this仍然指向window,普通函数中this指向undefined

ES5非严格模式

console.log(this);   //window
function fn(){
console.log(this);   //window
}
fn();

ES5严格模式 ES6

"use strict";
console.log(this);   //window
function fn(){
console.log(this);   //undefined
}
fn();

2.对象中的this

  • 对象方法中的this指向此对象,直接this指向对象外this的指向
var obj={
    a:1,
    b:function(){
        console.log(this);     // this指向当前对象自身obj
    },
    c:this.a     // this指向对象外this的指向
}

3.回调函数中的this 3种情况

  • 如果直接指向的回调函数,this指向最外层window
  • 如果通过arguments直接使用参数指向函数,this则指向执行当前函数的arguments
  • 如果回调函数通过call,apply,bind重新指向了新的对象时,this就是指向新对象
var obj = {
    a: function () {
        console.log(this,"____");
        var self=this;
        function fn1(fn) {
          console.log(this)//对象方法内的函数相当普通函数的执行  指向window
            fn();
            // arguments[0]();  //arguments
            // fn.call(self);  //obj
        }
        function fn2() {
            console.log(this);//window 回调函数中
        }
        fn1(fn2);
    },
  };
  obj.a();
var obj={
    b:1,
    a:function(){
       setTimeout(function(){
              console.log(this);   //window  尽管在setTimeout中,但是依旧是回调函数中的this指向
        }, 2000);
        setTimeout(function(obj){
              console.log(this)   //window   回调函数
              console.log(obj);  //obj    这个是外部传参,this作为参数传进来.this指向的是obj
        }, 2000,this);  
    }
}
obj.a();

4.事件中的this

var obj={
    b:1,
    a:function(){
      //   console.log(this);
      //   特殊的回调函数
      document.addEventListener("click",this.clickHandler);
      //   document.attachEvent("onclick",this.clickHandler);
    },
    clickHandler:function(e){
           console.log(this===document);//addEventListener事件侦听的对象 e.currentTarget
          // console.log(this===window);//IE8 attachEvent侦听事件时,this指向window
    } 
} 
obj.a();

5.ES6类中的this

  • 任何的静态方法中this都是当前类,也是构造函数
  • 静态方法中无法获取到实例化对象的this的
class Box{
    static _instance;
     constructor(){
         console.log(this);//指向被实例化的对象
     }
     static getInstance(){   //单例模式
         if(!Box._instance){
             Box._instance=new Box();
         }
         return Box._instance;
     }
     play(){
         console.log(this,"|");//指向被实例化的对象
     }
     static run(){
         // console.log(this);
         console.log(this===Box,"____");
         return this;   
     }

     static plays(){
         this.getInstance().play();
         var o=this.getInstance();   //单例模式的效果,获得的实例化都相同
         var o1=this.getInstance();
         console.log(o===o1);
     }
 }

 var b=new Box();//会执行构造函数,这是构造函数中this就是这个b对象
 b.play();//b对象下的方法play,因此play方法中this被指向b,谁执行play,this指向谁
 console.log(Box.run()===b);//false
 console.log(Box.run()===b.constructor);//true

6.ES5 面向对象中的this

function Box(){
    console.log(this);
}
Box.prototype.play=function(){    //相当于ES6中类中的动态方法中的this
    console.log(this);//this是指向执行该方法的实例化对象
}

Box.run=function(){   //相当于ES6中类中的静态方法中的this
    console.log(this);//Box
}

Box();//this是window或者undefined
var b=new Box();// this是实例化后b对象
b.play();

7.箭头函数

var obj = {
    a: function () {
      setTimeout(() => {
        console.log(this);//this是箭头函数外this的指向  所以this指向obj
        // 上下文环境中this的指向
      }, 2000);
    },
  };
  obj.a();

8.绑定this指向

call apply bind
function fn(){
console.log(this);
}
var obj={a:1}
fn.call(obj);//fn中this指向obj
fn.apply(obj);//fn中this 指向obj
fn.bind(obj)();//fn中this指向obj
原文地址:https://www.cnblogs.com/94-Lucky/p/13493332.html