Skip to content

Commit

Permalink
objects-classes, ch3: explaining the 'fix' for the statics subclass g…
Browse files Browse the repository at this point in the history
…otcha
  • Loading branch information
getify committed Jul 16, 2022
1 parent 25c4059 commit e909d38
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
2 changes: 1 addition & 1 deletion objects-classes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
* [Preface](../preface.md)
* [Chapter 1: Object Foundations](ch1.md)
* [Chapter 2: How Objects Work](ch2.md)
* [Chapter 3: Objects as Classes](ch3.md)
* [Chapter 3: Classy Objects](ch3.md)
* TODO
32 changes: 29 additions & 3 deletions objects-classes/ch3.md
Original file line number Diff line number Diff line change
Expand Up @@ -1099,7 +1099,7 @@ The `#printError()` static private function here has a `this`, but that's refere

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

#### Subclassing Gotcha
#### Gotcha: Subclassing With Static Privates and `this`

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

Expand Down Expand Up @@ -1129,7 +1129,7 @@ point.printID();

That works just fine.

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

```js
class Point2d {
Expand Down Expand Up @@ -1158,7 +1158,33 @@ Point3d.printError();

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.

But it fails, as shown by the last statement in that snippet. Beware that gotcha!
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.

There's a *fix*, though. In the static function, instead of `this.#errorMsg`, swap that for `Point2d.#errorMsg`, and now it works:

```js
class Point2d {
static #errorMsg = "Out of bounds."
static printError() {
// the fixed reference vvvvvv
console.log(`Error: ${Point2d.#errorMsg}`);
}

// ..
}

class Point3d extends Point2d {
// ..
}

Point2d.printError();
// Error: Out of bounds.

Point3d.printError();
// Error: Out of bounds. <-- phew, it works now!
```

If public static functions are being inherited, use the class name to access any private statics instead of using `this.` references. Beware that gotcha!

## Class Example

Expand Down

0 comments on commit e909d38

Please sign in to comment.