js中this指向问题

172 阅读3分钟

1.this的概述

1 this指向的是一个对象,函数执行的上下文对象;

2 在这里我把this理解为一个操作这个函数执行的句柄(操作者),就像一个人(this)拿着锯子(函数)去锯木头(函数执行的上下文对象功能);

  1. 全局环境中this指向全局变量(window);

  2. 函数中的this,由调用函数的方式来决定,

1)如果函数是独立调用的,在严格模式下(use strict)是指向undefined的,在非严格模式下,指向window

(2)如果这个函数是被某一个对象调用,那么this指向被调用的对象;

  1. 构造函数与原型里面的this

    构造函数里的this以及原型里的this对象指的都是生成的实例;(由new决定的)

通过new操作符可以初始化一个constructor的指向,new的作用就是创建一个对象的实例,constructor也就指向了一个新的执行环境“在这个对象之中”;

  1. 箭头函数按词法作用域来绑定它的上下文,所以this 实际上会引用到原来的上下文。

(箭头函数会保持它当前执行上下文的词法作用域不变,而普通函数则不会,箭头函数从包含它的词法作用域中继承了this的值)

(3) 根据函数的调用方式的不同,this会指向不同的对象

2 普通函数中的this指向

当一个函数并非一个对象的属性时,那么它就是被当做函数来调用的。在此种模式下,this被绑定为全局对象,在浏览器环境下就是window对象

//普通函数
  function f1() {
 console.log(this);
 }
  f1() //这里this会指向window,默认指向为window

3 定时器的this的指向

 setInterval(function () {
 console.log(this);
 },2000);//同理这里this也会指向window

4 对象中方法的this的指向

function Person() {
    console.log(this);
    this.sayHi = function () {
        console.log(this);
    }
}
var per = new Person();//对象中方法的this指向实例对象
per.sayHi();

5 原型对象方法的this的指向

  function Person() {}
  Person.prototype.sayHi = function () {
  console.log(this);
  };
  var per = new Person();
  per.sayHi();//this会指向Person,原型对象方法中的this指向实例对象

6 箭头函数的this指向

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

    var obj={
            a:function(){
                document.addEventListener("click",this.clicHandler);
            },
            clicHandler:function(e){
                setTimeout(()=>{
                    console.log(this);
                },2000);
            }
        }
        obj.a();//#document

7call apply bind的this指向

    fn.call(obj);//fn中this指向obj
    fn.apply(obj);//fn中this 指向obj
    fn.bind(obj)();//fn中this指向obj
    
        var obj={
             a:function(){
                 function fn(){
                     console.log(this);
               }
               fn();
              console.log(this);//window 如果是call apply bind 带入的是null,将会把这里的this重新指向window
             }
         }
    	obj.a();//window
         obj.a.call(null);//window

8 ES6中this指向

  // ES6类
       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,"____");
               // this就是当前类名也是构造函数
               // 任何的静态方法中this都是当前类
               // 静态方法中无法获取到实例化对象的this的
              return this;
           }
           
           var b=new Box();//会执行构造函数,这是构造函数中this就是这个b对象
      	   b.play();//b对象下的方法play,因此play方法中this被指向b,谁执行play,this指向谁