子クラスで getter/setter を上書きする場合は両方書かないとダメ
- カテゴリ:
- JavaScript
- コメント数:
- Comments: 0
◆ setter 時に追加処理を入れたくて setter だけ再定義したら getter が動かなくなる
◆ どちらかを再定義するなら両方書く必要あり
◆ どちらかを再定義するなら両方書く必要あり
こんなクラス定義があります
X は普通に
です
それを継承した Y1 では getter/setter を再定義していますが 特別なことはせず単に親に渡してるだけなので同じ結果です
それが set だけの Y2 になると
va の値が undefined になります
さらに継承した Z1, Z2 はそれぞれ Y1, Y2 と同じになります
Z1 は何も書かなくても Y1 を引き継いでいるのに Y2 は X を引き継いでくれていません
このように _va にデータはあるので getter だけが設定されていないです
getter か setter のどちらかを書く場合は もう一方も書かないと省略した場合に親クラスのを引き継いでくれないようです
クラス記法特有の仕様なのかもと思って確認しましたが 普通のプロトタイプチェインでも同じ挙動でした
class X {
get va() { return this._va }
set va(v) { this._va = v }
}
class Y1 extends X {
get va() { return this._va }
set va(v) { super._va = v }
}
class Y2 extends X {
set va(v) { super._va = v }
}
class Z1 extends Y1 {}
class Z2 extends Y2 {}
X は普通に
let a
a = new X()
a.va = 100
console.log(a.va)
// 100
です
それを継承した Y1 では getter/setter を再定義していますが 特別なことはせず単に親に渡してるだけなので同じ結果です
a = new Y1()
a.va = 100
console.log(a.va)
// 100
それが set だけの Y2 になると
a = new Y2()
a.va = 100
console.log(a.va)
// undefined
va の値が undefined になります
さらに継承した Z1, Z2 はそれぞれ Y1, Y2 と同じになります
a = new Z1()
a.va = 100
console.log(a.va)
// 100
a = new Z2()
a.va = 100
console.log(a.va)
// undefined
Z1 は何も書かなくても Y1 を引き継いでいるのに Y2 は X を引き継いでくれていません
a = new Y2()
a.va = 100
console.log(a._va)
// 100
このように _va にデータはあるので getter だけが設定されていないです
getter か setter のどちらかを書く場合は もう一方も書かないと省略した場合に親クラスのを引き継いでくれないようです
クラス記法特有の仕様なのかもと思って確認しましたが 普通のプロトタイプチェインでも同じ挙動でした
const x = {
get va() { return this._va },
set va(value) { this._va = value },
}
const y = {
set va(value) { this._va = value },
__proto__: x,
}
const z = {
__proto__: y,
}
z.va = 100
console.log(z.va)
// undefined