类是什么
虽然ES6提供了class
关键字用于创建对象,但其终究只是语法糖,底层并未实现。
1 2 3 4 5 6 7 8 9
| class Hero { constructor() { this.name = "张无忌"; this.sayMe = function () { console.log("this is 张无忌"); }; } }
|
类的声明
类的声明方式
1 2 3
| class name [extends]{ }
|
name
表示当前类的名称。此方法不允许再次声明已经存在的类,否则会抛出一个类型错误。
类的表达方式
1 2 3
| const MyClass = class [className] [extends]{ }
|
和函数表达式相同的一点是,类表达式可以是命名也可以是匿名的。如果是命名类表达式,这个名字只能在类体内部才能访问到。
构造函数
1 2 3
| class Hero { constructor() {} }
|
在一个类中只能有一个名为“ constructor”的特殊方法。类中出现多次构造函数(Constructor)方法将会抛出一个 SyntaxError错误。
在一个构造方法中可以使用Super关键字来调用一个父类的构造方法。
如果没有显式指定构造方法,则会添加默认的constructor方法。
如果不指定一个构造函数( constructor)方法,则使用一个默认的构造函数(constructor)
1 2 3 4 5 6 7 8 9 10 11
| class Hero { constructor() { this.name = "张无忌"; this.say = function () { console.log("Im am ", this.name); }; } }
let hero = new Hero(); hero.say();
|
getter和setter
在“类”的内部可以使用get和set关键字,对某个属性设置存值函数取值函数,拦截该属性的存取行为
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Hero { constructor() { this.v = 100; } get getV() { return this.v; } set setV(value) { this.v = value; } } var obj = new Hero(); console.log(obj.getV);
|
静态方法
在类的内部允许定义静态方法,静态方法不会被添加到当前类的实例中。通过类直接调用此方法。
1 2 3 4 5 6 7 8 9 10
| class Hero { constructor() { this.name = "张无忌"; } static sayMe() { console.log("this is 张无忌"); } }
Hero.sayMe();
|
在一个静态方法中调用另外一个静态方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Hero { constructor() { this.name = "张无忌"; this.sayMe = () => { console.log("this is ", this.name); Hero.sayYou(); }; } toString() { console.log("name toString", this.name); } static sayYou() { console.log("this is sayYou"); } static sayHe() { this.sayYou(); } }
let hero = new Hero(); hero.sayMe();
Hero.sayHe();
|
- 在
constructor
中只能通过类名调用 - 在静态方法中可以通过类名调用也可以通过
this
调用。
类的继承
类在继承时使用关键字extends
关键字即可。
1 2 3 4 5 6
| class Child extends Parent { constructor() { super(); this.age = 18; } }
|
继承的类会继承类的方法,静态方法和构造函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class Parent { constructor() { this.name = "parent"; this.sayMe = function () { console.log("this is sayMe"); }; } sayYou() { console.log("this is sayyou"); } static staticMethod() { console.log("this is staticMethod"); } }
class Child extends Parent { constructor() { super(); this.age = 18; } }
let child = new Child(); console.log(child); child.sayYou(); Child.staticMethod();
|
继承实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class myDate extends Date { constructor() { super(); } getFormattedDate() { let months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ]; return `${this.getDate()}-${months[this.getMonth()]}-${this.getFullYear()}`; } }
let date = new myDate();
console.log(date.getFormattedDate());
|
通过继承一个Date
对象,对其扩展自己的方法。
super关键字
super
关键字作为函数调用时,代表父类的构造函数。ES6要求子类的构造函数必须执行一次super
函数
super
虽然代表了父类A的构造函数,但是返回的是子类B的实例。
super
当作对象时,在普通方法中,指向父类的原型对象。在静态方法中,指向父类。
由于super
指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过super
调用的。
类的完整示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| class Parent { constructor(name) { this.name = name; } toString() { console.log("this is parent toString"); return "this is parent toString"; } static staticMethod() { console.log("this is parent static"); return "this is parent static"; } sayMe() { console.log("this is parent sayMe"); return "this is parent sayMe"; } }
Parent.prototype.sayYou = function () { console.log("this is parent sayYou"); return "this is parent sayYou"; };
class Child extends Parent { constructor(name, age) { super(name); this.age = age; super.sayMe(); super.sayYou(); } toString() { console.log("this is child toString", super.toString()); } static staticMethod() { console.log("this is child static", super.staticMethod()); } }
let child = new Child("XiaoKang", 18); console.log(child);
child.toString(); Child.staticMethod();
|