提问人:Géry Ogam 提问时间:4/8/2023 最后编辑:Géry Ogam 更新时间:6/1/2023 访问量:195
为什么禁止通过子类访问私有静态成员?
Why is access to private static members through a subclass forbidden?
问:
来自 MDN Web Docs:
私有静态字段有一个限制:只有定义私有静态字段的类才能访问该字段。这可能会导致在使用 时出现意外行为。在下面的示例中,当我们尝试调用时,指的是类(而不是类),因此会导致 .
this
this
Subclass
ClassWithPrivateStaticField
Subclass.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
为什么禁止通过子类访问私有静态成员?
答:
0赞
Bergi
4/8/2023
#1
相反,私有实例字段是继承的
不,他们也不是。私有字段不是以原型方式继承的,访问它们不遵循原型链。
静态字段和实例字段的区别在于,后者是由 创建的,它是“继承的”,因此它们也是默认在子类实例上创建的(在调用中)。静态属性没有等效的功能,当子类运行时,父类中没有代码运行(并且可以创建私有静态字段)。constructor
super()
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
就个人而言,我完全看不出静态私有属性有任何用处。它们等效于 在 旁边声明的局部变量,应按此处理。它们通常应该是蚂蚁,因为静态方法不应该携带任何状态,所以继承它们也没有好处。class
const
0赞
Géry Ogam
4/8/2023
感谢您分享您的观点。但是,您也看不到当前限制的任何好处。当前限制的主要缺点是,它通过创建一个异常使程序员的语言复杂化:除了私有静态字段之外,您还可以通过访问属性。因此,我将打开一个功能请求来解除该限制,这似乎是偶然的,正如 Barmar 在我的帖子的最后评论中解释的那样。this
评论
this
BaseClass.basePublicStaticMethod();
this