ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
我们可以通过class关键字来定义一个类:
- class Person{
- constructor(name,age){
- this.name=name;
- this.age=age
- }
- sayName(){ //--类似于存在类的原型对象中
- console.log(this.name)
- }
- }
- static personAttr = '静态属性';
- static personMethod(){
- console.log('这是静态方法');
- }
注意:
实例:
使用new创建Person的实例对象p1与p2:
- let p1 = new Person('zzy', 17, 'female');
- console.log(p1); // Person { name: 'zzy', age: 17, gender: 'female' }
- p1.sayName(); // zzy
- let p2 = new Person();
- console.log(p1.sayName===p2.sayName); // true
- // 说明由Person创建出来的实例对象都可以使用这个公共方法
-
- // 静态属性和静态方法只能由类本身去调用
- Person.personMethod(); // 这是静态方法
- console.log(Person.personAttr); // 静态属性
- p1.personMethod(); // 会报错,不能由实例对象调用
注意:
添加一个引用数据类型的属性:
- // 添加引用数据类型的属性
- test = [];
-
- ...
-
- // 在p1里添加一个元素
- p1.test.push('cute')
- console.log(p1);
此时再打印p1与p2可以看到:
这个元素在p1中被添加进去了,p2没有。,说明引用数据类型对应的是实例的私有属性。
添加一个基本数据类型的属性:
- // 基本数据类型对应的是实例的公共属性
- test1 = 'hello';
-
- ...
-
- console.log(p1.test1===p2.test1,'公共属性'); // true 公共属性
可以看到p1与p2中的test1是完全相等的 。
class可以通过extends关键字实现继承,子类可以没有构造函数,系统会默认分配。子类提供了构造函数则必须要显式调用super。super函数类似于借用构造函数。类似于.call()
- class Animal{
- constructor(name, age, gender){
- // 实例的私有属性
- this.name = name;
- this.age = age;
- this.gender = gender;
- console.log('父类构造器');
- }
- sayName(){
- console.log(this.name);
- }
- static animaiAttr = '父类静态属性';
- static animalMethod(d1){
- return d1 instanceof Animal;
- }
- }
- class Dog extends Animal{
- constructor(name, age, gender, type){
- // console.log('子类构造器'); 放在这里就先打印子类构造器
- super(name, age, gender);
- // console.log('子类构造器'); 放在这里就先打印父类构造器
- this.gender = gender;
- }
- };
注意: ES6 要求,子类的构造函数必须执行一次super函数。代表父类的构造函数。因此,当我们的的打印位置出现在super的先后次序不一样时会出现不一样的执行结果。作为函数时,super()只能用在子类的构造函数之中,用在其他地方就会报错。
- class 子类 extends 父类{
- //继承父类实例私有属性
- constructor(){
- super()
- //继承父类构造器
- }
- }
console.log(Dog.__proto__===Animal); // true
console.log(Dog.prototype.__proto__===Animal.prototype); // true