如何清楚地明白js中的this指向

102 阅读2分钟

this在JS中是一个非常重要的语法点,如果你没有弄明白它的含义和用法,那一定是完不成你所要完成的任务的,对JS的理解也是会很吃力的。首先呢,我们应该先明白它的概念:this是JS中的一个关键字,它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用,随着函数使用的场景不同,this指向也会发生变化,归根结底,谁调用了这个函数,this就指向这一对象。如果没有调用者,那就指向全局对象window。

我们先看一则基础案例

function fn(){
    console.log(this.a)
}

var obj={
    a:'111',
    f:fn
}
var a='222'

obj.f();//111
fn();//222

在上述代码中,fn这一函数被调用了两次,而这两次的结果都不相同,

很多人会认为,obj.fn()的调用中运行环境为obj,那么this指向一定是obj;

而在全局作用域下的fn(),函数中的this就会指向全局作用域window;

但是如果你能搞清楚this指向为什么会发生变化,是在什么时候发生变化的这两点,就真正知道是为什么了。

我们要知道,js中的数组、函数以及对象都属于引用数据类型,那么参数传递也就是引用传递;

上面的代码中,obj的两个属性类型是不同的,在内存中表现形式也不同;

函数在js中既可以当作值来传递,也可以当作对象和构造函数,所以在函数运行时需要确定当前的运行环境,this就会起到作用,所以说this会随着运行环境的改变而改变,同时,this只能在运行时才可以确定运行的环境。

使用场景

1.全局环境

普通函数调用时this指向的就是window

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

只要是在全局环境下调用的函数,this指向就是window

2.对象方法

作用域是对象时,this的指向就是该对象

var name='person';
var animal={
    name:'cat',
    eat:function(){
        console.log(this.name);
    }
}

animal.eat();//cat

因为eat这一函数是由animal调用的,所以说this指向是animal中的eat函数,所以结果是this.name,也就是'cat'。

3.构造函数

构造函数中this指向是实例对象。

var obj=function(a){
    this.a=a;
};

在这一构造函数obj中,this指向实例对象,所以在构造函数内部定义this.a,就相当于定义实例对象有一个p属性。

4.定时器调用

常用的定时器有setTimeout和setInterval,我们使用setTimeout:

setTimeout(() => {
    console.log(this);
})

定时器的调用this直接指向window。