重点内容
近期看到了很多关于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其中的部分,但是我们可以先留下一个印象,下次遇到这样的情况也是能快速的解决问题。还有现在这个博客的排版确实没有弄清楚,感觉很乱也是非常对不起大家和自己这么长的总结。