ECMAScript6: 类

来自CloudWiki
跳转至: 导航搜索

ES引入了class的概念,新的class写法让对象原型的写法更加清晰

定义类

class Car{
	// 等价于Car构造函数
	constructor(sColor,iDoors){
		this.color= sColor; 
		this.doors= iDoors;
	}
	// 等价于Car.prototype.showColor
	showColor(){
		console.log(this.color);
	}
}

let oCar = new Car("red",4);
oCar.showColor();

与函数一样,类也可以使用表达式的形式定义:

let Car = class {
	// 等价于Car构造函数
	constructor(sColor,iDoors){
		this.color= sColor; 
		this.doors= iDoors;
	}
	// 等价于Car.prototype.showColor
	showColor(){
		console.log(this.color);
	}
}

let oCar = new Car("red",4);
oCar.showColor();

使用类表达式,可以立即调用类构造函数从而构建一共类的单例对象:

let car = new class {
	// 等价于Car构造函数
	constructor(sColor,iDoors){
		this.color= sColor; 
		this.doors= iDoors;
	}
	// 等价于Car.prototype.showColor
	showColor(){
		console.log(this.color);
	}
}("red", 4);

car.showColor();

访问器属性

访问器属性是通过关键字get 和set来创建的,实际上是为某个属性定义取值和设值函数。

 
class Car{
	constructor(sName, iDoors){
		this._name= sName; 
		this.doors= iDoors;
	}
	// 只读属性
	get desc(){
		return `${this.name} is worth having.`;
	}
	
	get name(){
		return this._name;
	}
	
	set name(value){
		this._name = value; 
	}
}

let car = new Car("Benz", 4);
console.log(car.name);  // Benz
console.log(car.desc);  // Benz is worth having.
car.name = "Ferrari";
console.log(car.name);  // Ferrari
car.prototype.desc = "very good"; //TypeError: Cannot set property 'desc' of undefined

构造函数中定义了一个_name属性,前面的下划线是一种常见的约定符号,用于表示只能通过对象方法访问的属性。

当访问和赋值name时,实际时调用它的取值和设值方法。

静态方法

ES6 引入了关键字static ,用于定义静态方法。

使用static关键字定义的静态方法,只能通过类名来访问,不能通过实例来访问。

 
class Car{
	constructor(sName, iDoors){
		this.name= sName; 
		this.doors= iDoors;
	}
	
	showName(){
		console.log(this.name);
	}
	
	static createDefault(){
		return new Car("Audi", 4);
	}
}


let car = Car.createDefault();
car.showName();        // Audi
car.createDefault();   // TypeError: car.createDefault is not a function


类的继承

ES6提供了extends关键字,可以很轻松地实现类的继承。

 
class Person{
	constructor(name){
		this.name = name;
	}
	
	work(){
		console.log("working...");
	}
}

class Student extends Person{
	constructor(name, no){
		super(name); //调用父类的constructor(name)
		this.no = no;
	}
}

let stu = new Student("zhangsan", 1);
stu.work();  // woking...

注意:如果派生类中没有定义构造函数,那么当创建派生类的实例时会自动调用super( )并传入所有参数。

在派生类中,可以重写基类的方法。这将覆盖基类中的同名方法。

class Person{
	constructor(name){
		this.name = name;
	}
	
	work(){
		console.log("working...");
	}
}

class Student extends Person{
	constructor(name, no){
		super(name); //调用父类的constructor(name)
		this.no = no;
	}
	
	// 覆盖Person.prototype.work()方法
	work(){
		super.work();
		console.log("studying...");
	}
}

let stu = new Student("zhangsan", 1);
stu.work();  // working...
             // studying...