ES6静态成员被child继承类

ES6 static members are inherited by child classes

我发现 class 的静态成员由它在 JavaScript 中的子 classes 继承。我已经用 Chrome 67.0.3396.62、FireFox 60.0.1 和 节点 10.1.0.

但是在OOP中,静态成员和字段应该属于class而不是被继承,这不是很奇怪吗?

这是 JavaScript extends 的错误吗?

class A {
  static a () {
    console.log('==[static a]==')
  }
}

A.propA = { anything: '==[static data from A]==' }

class B extends A { }

console.log(B.a()) // "==[static a]=="
console.log(B.propA.anything) // "==[static data from A]=="

这是一个很好的link理解静态如何与下面的代码一起工作的例子。

class Triple {
  static triple(n) {
    if (n === undefined) {
      n = 1;
    }
    return n * 3;
  }
}

class BiggerTriple extends Triple {
  static triple(n) {
    return super.triple(n) * super.triple(n);
  }
}

console.log(Triple.triple());        // 3
console.log(Triple.triple(6));       // 18

var tp = new Triple();

console.log(BiggerTriple.triple(3));
// 81 (not affected by parent's instantiation)

console.log(tp.triple());
// 'tp.triple is not a function'.

直接回答你的问题:

Static method calls are made directly on the class and are not callable on instances of the class. Static methods are often used to create utility functions.

Is it a bug for JavaScript extends?

不,它完全按照设计工作。

So where did class B actually find its inherited propA property? Through which part of the prototype chain?

让我们先澄清两件事:

  • 函数是对象,这意味着它们有一个原型。默认情况下是 Function.prototype,这是定义 .call.apply 等方法的地方。
  • "Static members" 只是函数对象的属性

做的时候

class B extends A {}

然后为 B 创建了一个新的函数对象,它的原型是 A,而不是 Function.prototype,因此 A 的所有属性都是可通过 B.

访问

我们可以很容易地验证这一点:

class A {}
class B extends A {}
console.log(Object.getPrototypeOf(B) === A);