class
类的数据类型就是函数,类本身就指向构造函数,this关键字则代表实例对象
属性
静态属性
class本身的属性,直接定义在类内部的属性
class Example{
static a = 2
}
Example.b=1
Example.b // 1
公共属性
class Example{}
Example.prototype.a = 2
实例属性
实例属性除了定义在constructor()方法里面的this上面,也可以定义在类的最顶层
class Example {
a = 2
constructor(){
console.log(this.a)
}
}
name属性
返回跟在class后的类名
私有属性
- 只能在类的内部使用(this.xxx),如果在类的外部使用,就会报错
- 私有属性不限于从this引用,只要是在类的内部,实例也可以引用私有属性
class Point {
#x;
constructor(x = 0) {
this.#x = +x;
}
get x() {
return this.#x;
}
set x(value) {
this.#x = +value;
}
}
new.target属性
class Rectangle {
constructor(length, width) {
console.log(new.target === Rectangle);
this.length = length;
this.width = width;
}
}
var obj = new Rectangle(3, 4); // 输出 true
子类继承父类时,new.target会返回子类
class Rectangle {
constructor(length, width) {
console.log(new.target === Rectangle);
// ...
}
}
class Square extends Rectangle {
constructor(length, width) {
super(length, width);
}
}
var obj = new Square(3); // 输出 false
方法
constructor
类的默认方法(构造方法),创建类的实例化对象时被调用
class Example{
constructor(){
console.log('我是constructor');
}
}
new Example(); // 我是constructor
静态方法
在一个方法前,加上static关键字,就表示该方法不会被实例继承
- 如果静态方法包含this关键字,这个this指的是类,而不是实例。
- 父类的静态方法,可以被子类继承
- 从super对象上调用的
class Foo {
static classMethod() {
return 'hello';
}
}
Foo.classMethod() // 'hello'
var foo = new Foo();
foo.classMethod() // TypeError: foo.classMethod is not a function
原型方法
类的所有方法都定义在类的prototype属性上面。
class Example {
sum(a, b) {
console.log(a + b);
}
}
let exam = new Example();
exam.sum(1, 2); // 3
实例方法
class Example {
constructor() {
this.sum = (a, b) => {
console.log(a + b);
}
}
}
私有方法
class Foo {
#a;
#b;
constructor(a, b) {
this.#a = a;
this.#b = b;
}
#sum() {
return this.#a + this.#b;
}
printSum() {
console.log(this.#sum());
}
}
继承
- extends
- Object.getPrototypeOf(): 从子类上获取父类,可以使用这个方法判断,一个类是否继承了另一个类
- super:既可以当作函数使用,也可以当作对象使用
class A {
constructor() {
console.log(new.target.name);
}
}
class B extends A {
constructor() {
super();
}
}
new A() // A
new B() // B
super()内部的this指向的是B
``` class A { p() { return 2; } }
class B extends A { constructor() { super(); console.log(super.p()); // 2 } }
let b = new B();
在普通方法中,指向父类的原型对象;在静态方法中,指向父类。
<hr >
class A { constructor() { this.p = 2; } }
class B extends A { get m() { return super.p; } }
let b = new B(); b.m // undefined
由于super指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过super调用的
##
* 在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例。
* 在子类的静态方法中通过super调用父类的方法时,方法内部的this指向当前的子类,而不是子类的实例