静态属性和方法

有的时候,一些属性或方法是跟类相关的,而不是实例。

比如猫类的所属科目,那么这些属性或方法就被称为静态方法,有两种方法声明静态属性或方法。

  • 使用 static 关键字。
  • 通过 类名.属性名 = 属性值 的方式
$$jsdemo$$
$$edit$$
class Cat {
    // 通过 static 关键字
    static family = "猫"
    static sayFamily(){
        alert(`我属于${Cat.family}科动物。`)
    }
}

Cat.sayFamily() // 我属于猫科动物。

$$warning

静态属性或方法无法通过实例或 this 访问。

$$

$$jsdemo$$
$$edit$$
class Cat {
    // 通过 static 关键字
    static family = "猫"
}
Cat.sayFamily = function () {
    alert(`我属于${Cat.family}科动物。`)
}

const cat = new Cat()
cat.sayFamily() // cat.sayFamily is not a function

以下实例中,在构造方法中将实例放到了静态属性 cats 中,之后便能通过静态方法统计数据。

$$jsdemo$$
$$edit$$
class Cat {
    // 保存所有的猫
    static cats = []

    constructor(name) {
        this.name = name

        // 保存进数组
        Cat.cats.push(this)
    }

    static get catAmount() {
        return Cat.cats.length
    }

    static get names() {
        // 返回所有姓名的数组
        return Cat.cats.map((cat) => cat.name)
    }
}

const cat1 = new Cat("喵喵")
const cat2 = new Cat("加菲猫")
const cat3 = new Cat("暹罗猫")

alert(`总共有${Cat.catAmount}只猫。分别是${Cat.names.join(",")}。`)

练习

  1. 补全 Animal 的代码,使其能完美运行。
class Animal {
    // 补充这里
}

class Cat extends Animal {
    static family = "猫"
    constructor(name, age) {
        super(name, age)
    }
}

class Dog extends Animal {
    static family = "狗"
    constructor(name, age) {
        super(name, age)
    }
}

const cat1 = new Cat("喵喵", 5)
const cat2 = new Cat("加菲猫", 8)

const dog1 = new Dog("旺财", 12)
const dog2 = new Dog("泰迪", 6)

// 三眼鸭宠物医院接诊了4只宠物。
alert(`三眼鸭宠物医院接诊了${Animal.animalAmount}只宠物。`)
// 年龄最大的是叫旺财的狗, 12岁。
alert(
    `年龄最大的是叫${Animal.maxAgeAnimal.name}的${Animal.maxAgeAnimal.constructor.family}, ${Animal.maxAgeAnimal.age}岁。`
)

$$answer

$$jsdemo$$
$$edit$$
class Animal {
    // 保存所有的动物
    static animals = []

    constructor(name, age) {
        this.name = name
        this.age = age

        // 保存进数组
        Animal.animals.push(this)
    }

    static get animalAmount() {
        return Animal.animals.length
    }

    static get maxAgeAnimal() {
        return Animal.animals.reduce((a, b) => (a.age > b.age ? a : b))
    }
}

class Cat extends Animal {
    static family = "猫"
    constructor(name, age) {
        super(name, age)
    }
}

class Dog extends Animal {
    static family = "狗"
    constructor(name, age) {
        super(name, age)
    }
}

const cat1 = new Cat("喵喵", 5)
const cat2 = new Cat("加菲猫", 8)

const dog1 = new Dog("旺财", 12)
const dog2 = new Dog("泰迪", 6)

alert(`三眼鸭宠物医院接诊了${Animal.animalAmount}只宠物。`)
alert(
    `年龄最大的是叫${Animal.maxAgeAnimal.name}的${Animal.maxAgeAnimal.constructor.family}, ${Animal.maxAgeAnimal.age}岁。`
)

$$