JavaScript中this的指向

this常见的4中指向
1.在浏览器中


image.png

可以看到,打印出来的this指向的都是window对象,在函数中也是如此
2.在元素的监听事件中



这里我们有两个div,一个大的div1包着一个小的div2,我们给这个div1绑定一个点击侦听,并且在里面去打印这个this。


image.png

可以看到这里的this指向了div1这个元素,在研究this的时候我还惊奇的发现,e.target和e.currentTarget有点细微的区别。
上图的打印是点击小黄块触发的,也就是点击div2触发的,这个时候可以看到this指向的是div1,e.target是div2,e.currentTarget还是div1。接下来我们点击大红块看看会发生什么


image.png

点击红快快的时候看到e.target也变成了div1,所以这个时候得出,e.target指的是触发这个侦听事件的元素,就是你点的那个元素。e.currentTarget则是绑定侦听事件的元素,和this一样。他们俩是不变的,哪个元素绑定了点击侦听,他们俩就指向谁

3.对象中的this

 /**
     * 3.当this处在一个对象中,这个this指向的是这个对象本身
     */
    let obj = {
        a: 1,
        b: function () {
            console.log(this.a)
        }
    };
obj.b()

首先看一下打印结果


image.png

可以看到这里的this指向了这个obj
接下来我们看看去this在构造函数中的指向

这里先创建一个对象的构造函数
function addobj(a) {
        this.a = a
        this.d = 5
        console.log(this)
    }
先看看这里面的this指向什么,很显然指向的是window,没有new关键字在,这个函数就不是个构造函数,
他还是一个普通的函数,跟this的第一种指向一样,他指向的也是window。

接下来我们用上new关键字,来实例化一个对象

    function addobj(a) {
        console.log(this,'我是构造函数里的this')
        this.a = a
        this.d = 5
    }
    let obj = new addobj(6)
    console.log(obj,'我是构造出来的对象obj')
image.png

可以看到构造函数里的this打印出来和构造出的obj是一样的,这是为什么呢。原因就在new这个关键字中。
new关键字做了什么:创建一个对象,把this指向这个对象,然后给这个对象赋值,最后return这个对象,所以我们let 的obj的值,其实就是new关键字创建的对象,这就很合理的解释了,为什么构造函数中打印的东西会和构造出来的obj一样。其实他们本来就是同一个对象!

我们都知道对象的原型链指向的是构造函数的原型对象,也就是说obj.proto=>addobj.prototype。先来验证一下

    function addobj(a) {
        this.a = a
        this.d = 5
    }
    addobj.prototype = {
        b: 2,
    };
    let newobj = new addobj(1);
    console.log(newobj);

上面代码中给addobj这个函数的原型prototype赋值了一个对象,我们打印看看结果


image.png

可以看到,obj本身已经有了构造函数中的a和d属性,并且obj的proto中还有一个b,这个b当然就是构造函数的prototype上的属性。
那么这个时候我们看看this指向的是谁呢

    function addobj(a) {
        this.a = a
        this.d = 5
    }
    addobj.prototype = {
        b: 2,
        c: function () {
            console.log(this)
        }
    };
    // addobj.prototype.c()
    let newobj = new addobj(1);
    console.log(newobj);
    newobj.c()
image.png

可以看到,构造函数中的两个打印出来的东西还是一样的,那我们是不是可以理解为,函数中的this始终指向调用他的那个对象呢,
再来看一段代码验证猜想

    function addobj(a) {
        this.a = a
        this.d = 5
    }
    addobj.prototype = {
        b: 2,
        c: function () {
            console.log(this)
        }
    };
    addobj.prototype.c()
    let newobj = new addobj(1);
    console.log(newobj);
    newobj.c()
image.png

我们通过addobj.prototype去调用c,这个时候this指向的不是newobj了,他指向了addobj.prototype。
综上所述,this在对象中,指向的就是当前对象本身。

4.简单使用一下call aplay bind
在了解了上述知识之后,我们知道了this的指向,那在有些情况下,我们需要this不按照常规来指向,而是按照我们自己的意愿去指向,这个时候 call aplay bind 方法就派上用场了
call:

    let obj = {
        a:2
    }
    function f1() {
        console.log(this)
    }
    f1()
    f1.call(obj)
image.png

在f1函数中打印this,直接调用f1方法和通过call去调用打印出了不一样的值,
直接调用毋庸置疑,打印出的是window对象,因为函数中的this指向的就是window,
而当我们通过call方法,并且传入一个对象的时候,这个时候this的指向就发生变化了,他指向了obj这个对象。这样就做到了改变this 的指向了。
call方法还可以传入参数

    let obj = {
        a:2
    }
    function f1(...param) {
        console.log(this,param)
    }
    f1()
    f1.call(obj,1,2,3)
image.png

applay方法和call方法一样,只是在传入参数的时候call方法可以传任意形式的,而applay方法只能传入数组,

    f1.apply(obj,[1,2,3])

bind方法就是给当前this绑定一个对象,但是bind方法跟其他两个不一样,他会返回一个函数,这个函数如果不主动调用,他是不会执行的

    let obj = {
        a:2
    }
    function f1(...param) {
        console.log(this,param)
    }
    f1()
    let fu = f1.bind(obj,1,2)
    fu()
image.png

如果不去调用fu的话,这个函数是不会自己执行的哦!
以上均为个人理解,并不全面。

你可能感兴趣的:(JavaScript中this的指向)