书籍参考:《ECMAScript 6入门》 作者:阮一峰
文档参考:MDN
概念
ES6提供了Class
语句用于更的理解语义以及更接近传统的编程语言的写法。Class
可以当作ES5构造函数的一个语法糖。
传统的构造函数以及继承方法如下面这样来写的:
function Getname() {
this.name = 'wyz';
this.age = '29';
}
// 如果我们需要定义一个给所有基于Getname构造函数使用的方法
// 那么我们必须通过prototype对象上定义
Getname.prototype.getName = function(){
return (Name: ${this.name}, Age: ${this.age}
);
}
let gname = new Getname();
gname.getName(); //"Name: wyz, Age: 29"
通过上面的方法来创建一个“类”,对比其他语言是差距很大的,而且很难理解,ES6提供了一个新的语句Class
来创建类。
class Getname{
constructor(){
this.name = 'wyz';
this.age = '29';
}
getName(){
return (Name: ${this.name}, Age: ${this.age}
);
}
}
let gname = new Getname();
gname.getName(); //"Name: wyz, Age: 29"
通过ES6的Class
语句更能清晰的表达出类,这与传统的语言声明类很相似。在class中,constructor
方法是一个构造函数,类似于我们构造函数中编写给实例初始化的一些属性方法,而在constructor
之外定义的方法都是定义在原型上面的公用方法,这就很能理解为什么Class
是构造函数的语法糖了。
gname.constructor === Getname; // true
gname.getName === Getname.prototype.getName; // true
在使用Class语句的时候,需要注意下面几个点:
- 在定义类的时候,方法与方法之间不需要逗号间隔,在定语方法的前面也不需要添加
function
关键字。 - 在使用定义类之前需要实例化,并且需要加上new关键字,这与构造方法一致。
- 类的所有方法都是定义在prototype属性上的,并且可以通过
__proto__
访问,同时也可以直接在上面对类进行添加方法。 - 一个方法必须有
constructor
,如果没有,会默认添加一个空的constructor
。并且constructor
默认返回实例对象即实例对象的指针this
,我们可以显示的使用return
语句改变默认动作。 - 类必须要使用前定义,不存在变量提升。
- 类的内部使用严格运行模式。
- 子类同时具备
prototype
和__proto__
。__proto__
指向父类,而prototype
的__proto__
属性,指向父类的原型也就是父类的prototype
属性。
继承
Class
之间的继承通过extends
关键字来实现,这对比es5复杂的修改原型要容易得多,需要注意的是子类并没有this
指针,子类的this是通过先调用父类的构造方法得到this
然后在上面加工,所以在子类使用this
指针前必须使用调用父类的构造方法。
这与es5的构造函数不一样,es5是先创建子类的this
,然后在这个this
上面添加方法与属性。
一个子类通过在构造方法中使用super()
来调用父类构造方法创建this
,如果没有只有constructor
没有super()
,那么将会在实例的时候出错,如果即没有constructor
和super()
,那么会默认添加上。
class Getname{
constructor(){
this.name = 'wyz';
this.age = '29';
}
getName(){
return (Name: ${this.name}, Age: ${this.age}
);
}
}
class Getall extends Getname{
constructor(){
super();
this.gender = 'male';
}
getAll(){
return (Name: ${this.name}, Age: ${this.age}, Gender: ${this.gender}
);
}
}
let m = new Getall(); //继承了父类的初始化值。name: "wyz", age: "29", gender: "male"
m.getName(); //使用父类的方法。Name: wyz, Age: 29
Object.getPrototypeOf()
Object.getPrototypeOf()
方法的作用是从子类上获取父类,那么就可以把这个方法拿来判断一个子类是否继承于一个类
Object.getPrototypeOf(Getall) === Getname; //true
类的静态方法
在定义类中的所有方法都是定义在prototype
属性上的,那么就意味着所有的方法都会被继承,那如何来定义一个不被实例继承,而只能通过类本身调用的静态方法?ES6提供了static
关键字。在需要不被继承静态方法前,但这个静态方法会被子类继承,因为子类的proto
总是指向父类。
class Foo {
static classMethod() {
return 'hello';
}
}
let foo = new Foo();
foo.classMethod(); //foo.classMethod is not a function
class Fow extends Foo {
}
Fow.classMethod(); // 'heelo'
Fow.__proto__.classMethod === Foo.classMethod; //true
类的静态属性
ES6只定义了类的静态方法并没有定义类的静态属性,所以如果要定义类的静态属性只能通过下面这样来定义:
class Foo{
}
Foo.name = 'wyz';
但是ES7提出了一个议案,可以直接通过static
关键字来定义类的静态属性,目前babel已经支持了。
class Foo{
static name = 'wyz';
}
文完
《ES6-Class类》留言数:0