1 概述
class
能够让 js 像传统的面向对象语言(如 c++, java)一样定义类。
class
的所有实例方法都定义在类的 prototype
属性上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class TTT{ constructor(x,y){ this.x=x; this.y=y; } printMe(){ return 'x:' + this.x + ',y:' + this.y; } }
TTT.prototype = { constructor(){}, printMe(){} }
|
2 基本语法
2.1 不存在变量提升
使用的位置必须在定义之后,否则报错
2.2 不允许重复定义
重复定义类时,会报错
1 2 3
| class Foo {}; class Foo {};
|
1 2 3
| let Foo = class {}; class Foo {};
|
2.3 constructor 即构造函数
构造函数中的 this
代表实例对象
类名可被当成是构造函数的别名
1 2 3
| class A{
A.prototype.constructor === A
|
2.4 原型对象 prototype
- 类的所有实例共享原型
prototype
- 类的原型
prototype
的 constructor
属性指向类本身
- 实例的
constructor
属性指向类本身
1 2 3 4 5 6
| class A{
let a = new A();
A.prototype.constructor === A a.constructor === A
|
2.5 属性
2.5.1 字段
公有字段都是可编辑、可遍历、可配置、可继承的。
2.5.1.2 实例字段
实例字段是基于实例的变量或属性,用于保存实例的状态,由实例来调用。
可以在 constructor 、 实例方法 中定义,也可以在类的顶部定义。
1 2 3 4 5 6 7 8 9 10 11 12
| class A { prop2 = 2; constructor() { this.prop1 = 1; } setProp3(){ this.props = 3; } } let a = new A(); a.setProp3(); console.log(a.prop1, a.prop2, a.props);
|
2.5.1.2 类字段(静态字段)
使用 static
关键字修饰的字段,通常用于创建工具函数。
1.可以在类的顶层定义
2.可以在类的外部定义
1 2 3 4 5 6 7
| class A { static sProp3 = 3; } A.sProp4 = 4;
console.log(A.sProp3, A.sProp4);
|
2.5.2 方法
2.5.2.1 实例方法
是所有实例共享的方法,由实例来调用
- 无需写
function
关键字,方法间无需用逗号分隔
- 方法中的
this
代表实例对象
- 方法不可枚举(与ES5不同)
2.5.2.2 类方法(静态方法)
使用 static
关键字修饰的方法。静态方法不可遍历。
1、类的静态方法属于类,不属于类的原型,不能通过类的实例进行调用
2、 静态方法中的 this 表示类,而不是实例
3、 静态方法可以和实例方法重名
4、 静态方法可以被子类继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class A { static sNameA() { console.log("static sNameA"); } static sNameB(){ } sNameA() { this.prop3 = 3; console.log("sName"); } }
class B extends A {}
A.sName(); B.sNameA();
|
2.6 类的属性名,可以使用表达式
1 2 3 4 5 6 7
| let name = 'getName'; class A{ [name](){ } }
|
2.7 name属性返回类名
3 示例
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
|
class TTT{
constructor(x,y){ this.x=x; this.y=y; }
printMe(){ return 'x:' + this.x + ',y:' + this.y; } }
console.log('typeof(TTT): \n',typeof(TTT)); console.log('\nTTT === TTT.prototype.constructor \n', TTT === TTT.prototype.constructor);
let t=new TTT(1,2); console.log('\nObject.keys(TTT.prototype) : \n', Object.keys(TTT.prototype));
console.log('\nTTT.name \n',TTT.name);
let t2 = new TTT(3.4); console.log('\nt2.__proto__ == t.__proto__\n',t2.__proto__ == t.__proto__); t2.__proto__.printMe = function(){ return 't2 modify printMe'; } console.log('\nt.printMe()\n',t.printMe());
console.log('\nt.hasOwnProperty(x)\n',t.hasOwnProperty('x')); console.log('\nt.hasOwnProperty(printMe)\n',t.hasOwnProperty('printMe')); console.log('\nt.__proto__.hasOwnProperty(printMe)\n',t.__proto__.hasOwnProperty('printMe'));
|
输出如下:
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
| typeof(TTT): function
TTT === TTT.prototype.constructor true
Object.keys(TTT.prototype) : []
TTT.name TTT
t2.__proto__ == t.__proto__ true
t.printMe() t2 modify printMe
t.hasOwnProperty(x) true
t.hasOwnProperty(printMe) false
t.__proto__.hasOwnProperty(printMe) true
|