不同于其他面向对象语言,ES6以前的JavaScript中中没有class类的概念,主要是通过原型的方式来实现继承,JavaScript中引入了原型链,并且将原型链用来实现继承,其核心是利用原型使得一个对象继承另一个对象的方法和属性,JavaScript中原型继承的关键是将一个实例的原型对象指向另一个实例,因此前一个实例便可以获得后一个实例原型对象的属性和方法,例如:
function Father(){
this.age=30;
}
Father.prototype.work=function(){
return "hard work";
}
function Child(){
this.age=10;
}
//将child的原型指向Father构造函数的实例
Child.prototype=new Father();
Child.prototype.play=function(){
return "play";
}
var child=new Child();
console.log(child.play()) // play
console.log(child.work()) // work
看完了上面的JavaScript典型的原型继承,要回到ES6上面了,ES6中引入了类class 的概念,实际上是语法糖,很多都与构造函数相关,先看个例子:
// var Man =class{ 这么写也是可以的
class Man{
constructor(age) {
this.age=age;
}
grow(){
return this.age+1;
}
}
var cala=new Man(22);
console.log(cala.grow()); // 23
上面是一个简单的ES6写class的例子,可以看到的是,用class关键字定义类,里面的constructor指的是构造函数,在构造函数中定义私有属性,然后接着定义了一个grow方法,最后通过new关键字来实例化一个对象
在JavaScript中定义类和定义函数很相似,不过两者还是有些不同,函数声明可以提升,但是类声明则不行
var cala=new Man();
class Man{} // Man is not defined
ES6中的类使用 extends创建子类,每个类里面都会有一个constructor构造函数,实例化的时候必须用new关键字来调用类的构造函数,一个构造函数可以通过super来调用另一个构造函数
class Man{
constructor(age) {
this.age=age;
}
static work(){
return "hard work"
}
}
class Cala extends Man{
constructor(age){
super(age);
}
grow(){
return this.age+1;
}
}
var cala=new Cala(22);
console.log(cala.grow()) // 23
ES6中的class支持类支持在原型上定义访问器get,set属性
class Man{
constructor(age) {
this.age=age;
}
get getAge(){
return this.age;
}
set setAge(age){
this.age=age;
}
}
var cala=new Man(22);
console.log(cala.getAge) // 22
cala.setAge=33;
console.log(cala.getAge) // 33
ES6的class中支持静态方法,用关键字static来定义,熟悉面向类与对象的童鞋大多知道,静态方法属于类本身,是通过类来调用,不能通过实例来调用
class Man{
constructor(age) {
this.age=age;
}
static work(){
return "hard work"
}
}
console.log(Man.work()); // hard work
var cala=new Man(22);
console.log(cala.work()); // cala.work is not a function
结合上面JavaScript典型的原型继承和下面的ES6的类,可以看出在使用new关键字实例化对象的时候,实际上是调用了prototype上的构造函数,ES6的class本质就是语法糖,对于传统的写法来说,也是可以在ES6中适用的,类上的方法其实也就相当于定义在prototype上面