ES6中很多的新特性值得我们去学习,今天主要围绕最值得我们学习的class(类)来展开
类的概念一提出就使得我们JavaScript面向对象的编程更贴切,在以往我们通过构造函数来实例化对象总给人怪怪的感觉,我们会觉得对象为什么是从函数new出来的 而且构造函数的缺点也非常明显比如:他可以不通过 new关键字来使用再比如子类实例共享了父类构造函数的引用数据类型属性。
但这里说明一点class(类)的实质也是函数这点我们是可以验证的
class Example1 {
constructor(name) {
this.name = name;
}
}
console.log(typeof Example1)
我们可以看到会输出 function 这也证明类实际是一个语法糖 本质还是构造函数。
再说一些使用上的注意点:
- Class类 本质是函数
- 类定义不会被提升,这意味着,必须在访问前对类进行定义,否则就会报错
- 类中方法不需要 function 关键字。方法间不能加分号。
- 构造器(constructor)中的属性和方法在新的实例对象中也有
- 写在构造器(constructor)的方法实际是在原型链中的即prototype继承关系
Class类的继承
类的继承同很多面向对象语言一样使用extends关键字 这给了我们很多记忆点和便利
class Human {
constructor(name, sex) {
this.name = name;
this.sex = sex;
}
showInfo() {
console.log(`我叫${this.name}我是${this.sex}生`);
}
}
class ChildClass extends Human {}
let child = new ChildClass("Olof", "男");
child.showInfo();
这里会输出你希望看到的内容,说明我们的ChildClass类继承了Human类他里面没有任何内容但他可以使用父类的方法。
下面的情况是如果我们需要子类也有他自己的属性或方法
class F {
constructor() {
this.Name = "company";
}
print() {
console.log(`名字是${this.Name}`);
}
}
//这个时候子类没有声明自己的this C就是完全继承F相当于一个拷贝
class C extends F {
constructor() {
super();
}
}
// super()不传参数在这里相当于C.prototype.constructor.call(this)
let c = new C();
console.log(c.Name);
c.print()
//子类拥有自己的属性和方法且继承父类
class T extends F {
constructor(Name, where) {
super()
this.Name = Name;
this.where = where;
}
printf() {
console.log(`${this.Name}位于${this.where}`);
}
print() {
super.print();
}
}
let t = new T('home', 'wuhan');
t.printf()
t.print()
上面代码我们模拟的子类继承父类同时拥有自己的属性但也有几点注意点:
首先是super()的三个作用(充当角色):
- 父类构造函数
- 父类原型对象
- 父类
另外子类构造函数必须要调用一次super(),且必须在this使用之前调用
因为子类的this必须要利用父类的构造函数创建,可以获取父类的实例方法和实例属性,然后在此基础上添加自身的属性和方法,生成自己的this,于是在调用super之前,子类是没有this存在的。
总结:
ES5的继承,实质上是先创造子类的实例对象this,然后再将父类的方法添加到this上(Parent.call(this))
ES6的继承,需要先创建父类的this,子类调用super继承父类的this对象,然后再加工。
静态属性,静态方法,实例属性,实例方法
class Attr {
static name = 'Olof';
static say() {
console.log('hello word');
}
say() {
console.log('hhhhhhh');
}
name = 'name';
}
console.log(Attr.name);
Attr.say();
let attr = new Attr();
console.log(attr.name);
attr.say();
console.log(attr.name);
我们通过static关键字来表示静态属性和方法 下面的输出语句也来引出我们的结论:
- 静态属性和方法只能通过类本身来调用或者在类的内部使用
- 子类通过继承只能找到实例属性和方法也就是我们写在prototyoe原型上的
- 子类继承的属性也为原型属性和方法
如有错误,请指正!