从前有匹马叫代码
心若没有栖息的地方,到哪里都是流浪

我们可以把一个方法赋值给类的函数本身,而不是赋给它的 "prototype" 。这样的方法被称为 静态的(static)。

例如这样:

class Animal {
    static staticProperty = 'staticProperty'
    static staticMethod() {
        console.log('staticMethod');
    }
}

它们等价于这样:

class Animal {}
    Animal.staticProperty = 'staticProperty';
    Animal.staticMethod = function() {
        console.log('staticMethod')
    }

在静态方法中 this 指向 当前类

class Animal {
    static staticProperty = 'staticProperty'
    static staticMethod() {
        console.log(this === Animal);
    }
}

Animal.staticMethod();//true

静态属性和方法是可被继承的

class People {
    static homeland = '中国';
    static staticMethod() {
        console.log(`${this.homeland}-${this.name}`);
    }
}

class Peng extends People {
    static name = '谢展鹏';
}

Peng.staticMethod();//中国-谢展鹏

为什么静态属性是可继承的,extends 到底做了什么?

当我们使用 extends 来实现继承时,它做了两件事:

  1. 在构造函数的 "prototype" 之间设置原型(为了获取实例方法)
  2. 在构造函数之间会设置原型(为了获取静态方法)

让我们来验证一下:

class Animal{
    static staticProperty = 'static Property';
    static staticMethod() {
        console.log('staticMethod');
    }
    run() {
        console.log('I\'m running!');
    }
}

class Rabbit extends Animal{}

console.log(Rabbit.__proto__ === Animal);// true
Object.keys(Rabbit.__proto__).forEach(k=>console.log(k)); //staticPropert

new Rabbit().run(); //I'm running!

console.log(Rabbit.prototype.__proto__ === Animal.prototype);//true

//解释一下: 因为 const rabbit = new Rabbit() 实例并没有run方法,所以实例在原型链上查找,大概顺序是这样的
// rabbit -> rabbit.__proto__(Rabbit.prototype) -> rabbit.__proto__.proto__(Animal.prototype)

 

在JS中所有函数的默认__proto__都是Function.prototype,对于内建的 Object 构造函数而言,Object.__proto__ === Function.prototype

 

推荐阅读 :《现代JavaScript教程》- 静态属性和静态方法

 

posted on 2021-02-17 21:13  从前有匹马叫代码  阅读(1441)  评论(0编辑  收藏  举报