前端设计

javascript中的this关键字到底是什么?

2019-11-18

javascript中的this关键字到底是什么?


this是什么?

this是指包含它的函数作为方法被调用时所属的对象。这句话理解起来感觉还是很拗口的,但是如果你把它拆分开来变成这三句话后就好理解一点了。


1.包含它的函数

2.作为方法被调用时

3.所属的对象


来看个简单的代码压压惊:

 function showName(){

     console.log(this); //window

 }

showName();


参照上面的那三句话来解剖一下这个代码,首先this被showName函数包含了,其次showName()被调用了,最后是被谁调用了呢,我们知道全局定义的函数都是挂载到window对象上面的showName()相当于window.showName();所以this在这里就代表了window。如果还不明白的话我就简单粗暴点讲:


谁特么的调用了我,我就是谁的对象,谁特么的最后调用了我,我就是谁的对象。


继续看代码示例加深理解:

function testFun () {

    var name="hello this!";

    console.log(this.name);

}

testFun();

我们分析一下,因为test()函数是在全局中被window对象所调用的,那么this就理所当然的是指向window对象了,可是name变量是定义在testFun函数里面的,window对象中并没有定义name变量,当然也就不会打印出"hello this"这个字符串了。



那如果是这样呢?

var name = "hey";

function testFun() {

    var name = "hello this!";

    console.log(this.name);

}

testFun();

此时定义了一个全局变量name,即在window对象上定义了name,因此会打印出"hey"字符串来。



继续看个稍微复杂一点的:

var obj={

    a:"哈哈哈",

    b:function(){

        var a="嘿嘿嘿";

        console.log(this.a);

    }

};

obj.b();

this被包含在函数b()中,但是因为是被对象obj所调用的,因此this属于对象obj,所以会打印出字符串"哈哈哈";


 

前面提到过 谁调用了我,我就属于谁,谁最后调用了我,我就属于谁。大家看下下面这个例子

var obj = {

    a:10,

    b:{

        fn:function(){

            console.log(this.a); //undefined

        }

    }

};

obj.b.fn();

在这个例子中对象obj是在window上面定义的,所以obj.b.fn()=window.obj.b.fn(),那么大家会说this不是被window对象,或者被b调用了吗,请注意此时this最后是被fn锁调用的,所以this属于函数fn,因为在函数fn中并没有定义变量a,所以会打印出undefined;


大家可能还会经常遇到以下几种情况,但是只要牢记我说的那句话就不会有太大的问题。


<div class="box">

    <button type="button" id="btn">我是一个按钮</button>

</div>

<script>

    var btn=document.getElementById("btn");

    btn.οnclick=function(){

        console.log(this);//btn

    }

</script>


 

this被btn调用所以this属于这个btn按钮对象,看效果图。


javascript中this1.jpg


 


接下来我们思考一下this在构造函数中的指向


我们知道构造函数也是一个定义在window上面的函数,,所以构造函数里面的this属于window对象。看代码:


function People(){

    var name1="aaa";

    this.name2="bbb";

    console.log(this);

}

People();

console.log(this.name1);

console.log(name2);


效果图:

javascript中this2.jpg

因为this是指向window,而name1是定义在局部函数里面因此为undefined,this.name2="bbb";相当于是在window上面声明了一个变量。


上面讲的构造函数都是直接调用的,那如果构造函数是通过new实例化出来的this又会指向谁呢?


function People(){

    var name1="aaa";

    this.name2="bbb";

    console.log(this);

}

var xiaoming=new People();

console.log(xiaoming .name1);

console.log(xiaoming.name2);


 

效果图:

javascript中this3.jpg


我们发现this指向了People对象,name1此时为undefined,name2为"bb",这是问什么呢?


这是因为原本的构造函数是window对象的方法,如果不用new操作符而直接调用,那么构造函数的执行对象就 是window,即this指向了window。现在用new操作符后,this就指向了新生成的对象。