为什么禁止通过子类访问私有静态成员?

Why is access to private static members through a subclass forbidden?

提问人:Géry Ogam 提问时间:4/8/2023 最后编辑:Géry Ogam 更新时间:6/1/2023 访问量:195

问:

来自 MDN Web Docs

私有静态字段有一个限制:只有定义私有静态字段的类才能访问该字段。这可能会导致在使用 时出现意外行为。在下面的示例中,当我们尝试调用时,指的是类(而不是类),因此会导致 .thisthisSubclassClassWithPrivateStaticFieldSubclass.publicStaticMethod()TypeError

class ClassWithPrivateStaticField {
  static #privateStaticField = 42;

  static publicStaticMethod() {
    return this.#privateStaticField;
  }
}

class Subclass extends ClassWithPrivateStaticField {}

Subclass.publicStaticMethod();
// TypeError: Cannot read private member #privateStaticField from an
// object whose class did not declare it

[...]

建议您始终通过类名访问私有静态字段,而不是通过 访问私有静态字段,这样继承就不会破坏该方法。this

因此,不能在静态方法中用于访问私有静态成员(上述字段的示例也适用于方法),因为它会中断子类。this

但是,可以在实例方法中用于访问私有实例成员(以下字段的示例也适用于方法),因为它适用于子类实例:this

class ClassWithPrivateInstanceField {
  #privateInstanceField = 42;

  publicInstanceMethod() {
    return this.#privateInstanceField;
  }
}

class Subclass extends ClassWithPrivateInstanceField {}

new Subclass().publicInstanceMethod(); // 42

为什么禁止通过子类访问私有静态成员?

JavaScript 继承 语言设计 静态 私有成员

评论

0赞 katniss 4/8/2023
不是在摘录的末尾说,“所以继承不会破坏方法”吗?
1赞 Géry Ogam 4/8/2023
@Barmar我不敢苟同,它确实存在于静态方法中:例如,works。thisBaseClass.basePublicStaticMethod();
1赞 Barmar 4/8/2023
右。我认为这是因为访问普通字段遵循原型链,但私有字段没有——这就是使它们私有的原因。
2赞 Barmar 4/8/2023
由于实例字段是实例的属性,因此无法通过原型访问它们。原型链用于方法和静态字段。
1赞 Barmar 4/8/2023
我不觉得这是一个深思熟虑的设计决定,而是从实现中掉出来的东西。通过禁用原型链使它们私有化,您将无法通过 访问它们。this

答:

0赞 Bergi 4/8/2023 #1

相反,私有实例字段是继承的

不,他们也不是。私有字段不是以原型方式继承的,访问它们不遵循原型链。

静态字段和实例字段的区别在于,后者是由 创建的,它是“继承的”,因此它们也是默认在子类实例上创建的(在调用中)。静态属性没有等效的功能,当子类运行时,父类中没有代码运行(并且可以创建私有静态字段)。constructorsuper()extends

评论

0赞 Géry Ogam 4/8/2023
“私有字段不是原型继承的,访问它们不遵循原型链。”是的,我不应该说私有实例字段是继承的,我应该说它们可以从声明它们的类的实例方法访问
0赞 Géry Ogam 4/8/2023
“静态属性没有等效的功能” 公共静态字段是继承的,那么为什么不私有静态字段呢?这种限制有什么好处?缺点是你不能再使用了。对我而言,私有财产应该是指只能在类主体内访问的财产;它不应该意味着只能通过该类或由该类构造的实例在类主体中访问的属性(这太严格了)。this
0赞 Bergi 4/8/2023
@GéryOgam静态属性是以原型方式继承的,但它们也不会在子类上重新创建。关于方法的可访问性,您很少希望在静态方法中使用,显式引用该类适用于更多调用并导致更清晰的代码。this
0赞 Bergi 4/8/2023
就个人而言,我完全看不出静态私有属性有任何用处。它们等效于 在 旁边声明的局部变量,应按此处理。它们通常应该是蚂蚁,因为静态方法不应该携带任何状态,所以继承它们也没有好处。classconst
0赞 Géry Ogam 4/8/2023
感谢您分享您的观点。但是,您也看不到当前限制的任何好处。当前限制的主要缺点是,它通过创建一个异常使程序员的语言复杂化:除了私有静态字段之外,您还可以通过访问属性。因此,我将打开一个功能请求来解除该限制,这似乎是偶然的,正如 Barmar 在我的帖子的最后评论中解释的那样。this