class私有属性(方法)继承问题
yaomk opened this issue · comments
阮老师好。
在Class 的继承-3.super关键字一章中,提到
ES6 规定,在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例。
如果父类有私有属性的话,子类继承后问题,有些疑问,举个例子:
class A {
#name = 'class A'
print() {
console.log(this.#name)
}
}
class B extends A {
#name = 'class B'
print() {
super.print()
console.log(this.#name)
}
}
let a = new A, b = new B
a.print() // class A
b.print() // class A class B
当我首次这样运行时,对结果感觉很疑惑,在B
中我已经改写了私有属性#name
的值,为什么调用b.print()
却依然打印出来class A
?这没有符合原文的描述。后来使用babel编译过后大致明白,当类使用私有属性就创建了一个this为键值,私有属性为value的WeakMap(方便理解:{父类实例的this => 'class A'})。当子类继承时,由于重写了#name
,所以又新创建了一个WeakMap:{子类实例的this => 'class B'},同时又在父类的WeakMap里新增了一个子类实例this的键值对{子类实例的this => 'class A'}。当调用super.print()
就返回了class A
。
我描述的可能不够清楚,我现在疑问是私有属性、方法是否是像babel编译的那样子,借助了WeakMap?私有属性、方法是否可以继承?在以后私有属性、方法正式成为标准时,使用上有什么注意的地方?是否应该尽量避免继承有私有属性的类?
新建子类实例时,会自动执行一次父类的构造函数。
新建子类实例时,会自动执行一次父类的构造函数。
这个似乎不能解释上边例子里子类实例调用print()打印出来的结果,为什么会打印出来’class A‘。
class A {
name = 'class A'
print() {
console.log(this.name)
}
}
class B extends A {
name = 'class B'
print() {
super.print()
console.log(this.name)
}
}
let a = new A, b = new B
a.print() // class A
b.print() // class B class B
普通实例属性为什么可以重写,而继承过来的私有属性就不能重写呢?
私有属性只限于它所在的类,子类拿不到父类的私有属性。