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...