Skip to content

Commit f394631

Browse files
committed
objects-classes, ch3: added info about nuances with class initialization ordering
1 parent 73cac51 commit f394631

File tree

1 file changed

+40
-3
lines changed

1 file changed

+40
-3
lines changed

objects-classes/ch3.md

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ class Point3d {
270270

271271
| TIP: |
272272
| :--- |
273-
| You can think of public field declarations as if they appear at the top of the constructor, each prefixed with an implied `this.` that you get to omit in the declarative `class` body form. |
273+
| You can mostly think of public field declarations as if they appear at the top of the `constructor(..)`, each prefixed with an implied `this.` that you get to omit in the declarative `class` body form. But, there's a catch! See "That's Super!" later for more information about it. |
274274

275275
Just like computed property names (see Chapter 1), field names can be computed:
276276

@@ -486,7 +486,7 @@ The ability for methods of the same name, at different levels of the inheritance
486486

487487
### That's Super!
488488

489-
In addition to a subclass method accessing an inherited method definition (even if overriden on the subclass) via `super.` reference, a subclass constructor can manually invoke the inherited base class constructor via `super(..)` function invocation:
489+
In addition to a subclass method accessing an inherited method definition (even if overriden on the subclass) via `super.` reference, a subclass constructor must manually invoke the inherited base class constructor via `super(..)` function invocation:
490490

491491
```js
492492
class Point2d {
@@ -516,7 +516,44 @@ point.toString(); // (3,4,5)
516516

517517
| WARNING: |
518518
| :--- |
519-
| An explicitly defined subclass constructor *must* call `super(..)` to run the inherited class's initialization, and that must occur before the subclass constructor makes any references to `this` or finishes/returns. Otherwise, a runtime exception will be thrown when that subclass constructor is invoked (via `new`). If you omit the subclass constructor, the default constructor automatically thankfully invokes `super()` for you. |
519+
| An explicitly defined subclass constructor *must* call `super(..)` to run the inherited class's initialization, and that must occur before the subclass constructor makes any references to `this` or finishes/returns. Otherwise, a runtime exception will be thrown when that subclass constructor is invoked (via `new`). If you omit the subclass constructor, the default constructor automatically -- thankfully! -- invokes `super()` for you. |
520+
521+
One nuance to be aware of: if you define a field (public or private) inside a subclass, and explicitly define a `constructor(..)` for this subclass, the field initializations will be processed not at the top of the constructor, but *between* the `super(..)` call and any subsequent code in the constructor.
522+
523+
Pay close attention to the order of console messages here:
524+
525+
```js
526+
class Point2d {
527+
x
528+
y
529+
constructor(x,y) {
530+
console.log("Running Point2d(..) constructor");
531+
this.x = x;
532+
this.y = y;
533+
}
534+
}
535+
536+
class Point3d extends Point2d {
537+
z = console.log("Initializing field 'z'")
538+
539+
constructor(x,y,z) {
540+
console.log("Running Point3d(..) constructor");
541+
super(x,y);
542+
543+
console.log(`Setting instance property 'z' to ${z}`);
544+
this.z = z;
545+
}
546+
toString() {
547+
console.log(`(${this.x},${this.y},${this.z})`);
548+
}
549+
}
550+
551+
var point = new Point3d(3,4,5);
552+
// Running Point3d(..) constructor
553+
// Running Point2d(..) constructor
554+
// Initializing field 'z'
555+
// Setting instance property 'z' to 5
556+
```
520557

521558
#### Which Class?
522559

0 commit comments

Comments
 (0)