Skip to content

Commit e909d38

Browse files
committed
objects-classes, ch3: explaining the 'fix' for the statics subclass gotcha
1 parent 25c4059 commit e909d38

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

objects-classes/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@
1010
* [Preface](../preface.md)
1111
* [Chapter 1: Object Foundations](ch1.md)
1212
* [Chapter 2: How Objects Work](ch2.md)
13-
* [Chapter 3: Objects as Classes](ch3.md)
13+
* [Chapter 3: Classy Objects](ch3.md)
1414
* TODO

objects-classes/ch3.md

+29-3
Original file line numberDiff line numberDiff line change
@@ -1099,7 +1099,7 @@ The `#printError()` static private function here has a `this`, but that's refere
10991099

11001100
Remember: private statics are similarly not-inherited by subclasses just as private members/methods are not.
11011101

1102-
#### Subclassing Gotcha
1102+
#### Gotcha: Subclassing With Static Privates and `this`
11031103

11041104
Recall that inherited methods, invoked from a subclass, have no trouble accessing (via `this.#whatever` style references) any privates from their own base class:
11051105

@@ -1129,7 +1129,7 @@ point.printID();
11291129

11301130
That works just fine.
11311131

1132-
Unfortunately, and (to me) a little unexpectedly/inconsistently, the same is not true of private statics accessed from inherited public static functions:
1132+
Unfortunately, and (to me) quite unexpectedly/inconsistently, the same is not true of private statics accessed from inherited public static functions:
11331133

11341134
```js
11351135
class Point2d {
@@ -1158,7 +1158,33 @@ Point3d.printError();
11581158

11591159
The `printError()` static is inherited (shared via `[[Prototype]]`) from `Point2d` to `Point3d` just fine, which is why the function references are identical. Like the non-static snippet just above, you might have expected the `Point3d.printError()` static invocation to resolve via the `[[Prototype]]` chain to its original base class (`Point2d`) location, thereby letting it access the base class's `#errorMsg` static private.
11601160

1161-
But it fails, as shown by the last statement in that snippet. Beware that gotcha!
1161+
But it fails, as shown by the last statement in that snippet. The reason it fails here, but not with the previous snippet, is a convoluted brain twister. I'm not going to dig into the *why* explanation here, frankly because it boils my blood to do so.
1162+
1163+
There's a *fix*, though. In the static function, instead of `this.#errorMsg`, swap that for `Point2d.#errorMsg`, and now it works:
1164+
1165+
```js
1166+
class Point2d {
1167+
static #errorMsg = "Out of bounds."
1168+
static printError() {
1169+
// the fixed reference vvvvvv
1170+
console.log(`Error: ${Point2d.#errorMsg}`);
1171+
}
1172+
1173+
// ..
1174+
}
1175+
1176+
class Point3d extends Point2d {
1177+
// ..
1178+
}
1179+
1180+
Point2d.printError();
1181+
// Error: Out of bounds.
1182+
1183+
Point3d.printError();
1184+
// Error: Out of bounds. <-- phew, it works now!
1185+
```
1186+
1187+
If public static functions are being inherited, use the class name to access any private statics instead of using `this.` references. Beware that gotcha!
11621188

11631189
## Class Example
11641190

0 commit comments

Comments
 (0)