this的用法

重点内容
近期看到了很多关于js当中比较容易弄错的this问题,自己也在学习react,react中也有一个关于用bind方法绑定this这样的情况,本篇也不仅仅是记录this的用法,还有ES6当中的箭头函数,以及类当中都会用到this。
在自己看来目前用到this的地方有三处,第一就是构造函数及普通函数中会用到this,第二就是ES6的箭头函数中也是会经常用到this,第三就是在ES6的类中也会用到,博主也是用自己的语言来讲述自己遇到的this问题,如果还有遗漏的地方,欢迎大家指正。
首先第一点,在构造函数中使用this

  function Car(color,owner) {
    console.log(this);
    this.color = color;
    this.owner = owner;
}

var car = new Car('red','qiugu');
console.log(car);  

这里写图片描述
可以看到内部打印的this和外部的Car实例的this实际上是一致的,那么其实我们就可以做这样的结论,在构造函数中,this其实就是指向构造函数生成的实例,这个大家很好理解,再来看这个

var obj = {
    name: 'qiugu',
    sayHello: function(){
        console.log(this);
        console.log(`i am ${this.name}`);
    }
}

var result = obj.sayHello;
result();
这个案列其实就比较容易犯错的,乍一看this.name这个this肯定是指向这个obj对象的,所以this.name的值肯定就是指向obj里面的name了,我们来看控制台打印的结果

这里写图片描述
this指向了window,所以输出的就只有“i am”,而没有this.name的值,而如果我们改变一下调用sayHello方法的“人”,也就是我们用obj来调用方法,结果就得到了我们想要的“qiugu”,所以this这里是分两种情况的,一种指向window,一种则是指向了当前调用方法的receiver,所以判断this的指向,还需要根据this所在的上下文来判断this究竟是指向window还是指向当前调用的函数,正因为this这种特性,有的时候我们需要强制来改变this的指向,就需要用到call,apply已经bind,感兴趣的同学可以看看博主之前写的关于call的一些介绍,这里重点说下bind,因为在react中也用到了bind来绑定方法,那么我们在什么情况下才会需要用到bind的方法呢

        var obj = {
            name: 'qiugu'
        }

        function sayName(){
            console.log(this.name);
        }
        var result = sayName.bind(obj);
        result();   

通过控制台的结果我们可以看到结果正是“qiugu”,这里可以看到bind与call/apply不一样的地方就在于bind绑定函数返回的是一个函数定义,所以我们需要用一个变量来接受,然后再执行函数。
再来看ES6的类当中,因为ES6的类本质还是基于原型的,所以子类继承父类是没有自己的this,因此我们需要用this来获得父类的this.

class Parent {
            constructor(name,age) {
                this.name = name;
                this.age = age;
            }
            toString() {
                return 'My name is ' + this.name + ' and my age is ' + this.age;
            }

        }

        class Children extends Parent {
            constructor(name,age,height) {
                // super(name,age);
                this.height = height;
            }
            toValue() {
                return this.height + super.toString();
            }
        }
        let children = new Children('marry',22,168);
        console.log(children);

然后直接在控制台看到报错了,
这里写图片描述
说的很明白,缺少super方法,我们添加上super方法以后,则打印出这个chilren类
这里写图片描述
同时我们可以看到chilren类里面的proto属性指向的就是Parent的父类,另外需要注意的是不管是父类还是子类,在constructor构造器外定义的方法,直接打印都是看不到,都是存在类的原型当中,不是类的实例的原型,就是类本身的实例中,我们在打印toValue的方法,看看super是指什么

console.log(children.toValue());

这里写图片描述

super其实就是指代父类,super.toString()的方法也就是调用父类的toString()的方法,所以才有了我们的输出的结果。
最后再来说说箭头函数,就是因为this的复杂性,所以为了简化this的使用,ES6出现了箭头函数这样的简写函数的方式,记住一句话,箭头函数中的this对象是定义时所在的对象,而不是使用时所在的对象,并且call之类的改变this指向的语法都会失效。
到现在博主也是可能只弄明白了this其中的部分,但是我们可以先留下一个印象,下次遇到这样的情况也是能快速的解决问题。还有现在这个博客的排版确实没有弄清楚,感觉很乱也是非常对不起大家和自己这么长的总结。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值