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('这是静态方法');
}
注意:
- constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法 -- 这个方法是必须提供的, 如果没有显式定义,默认提供一个空的constructor方法。
实例:
使用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(); // 会报错,不能由实例对象调用
注意:
- 这里定义的sayName方法是一个公共方法,类似于存在于原型对象Person.prototype中,由Person创建的实例对象都可以使用这个方法。
- 用static定义的属性和方法是静态属性与方法,实例对象不可调用,只能由类本身去直接调用。
***
- 引用数据类型对应的是实例的私有属性
- 基本数据类型对应的是实例的公共属性
添加一个引用数据类型的属性:
// 添加引用数据类型的属性
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()
父类Animal:
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()
//继承父类构造器
}
}
- 子类对象通过__proto__指针指向父类对象
console.log(Dog.__proto__===Animal); // true
- 子类原型对象继承父类原型对象
console.log(Dog.prototype.__proto__===Animal.prototype); // true