You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: objects-classes/ch3.md
+73-1Lines changed: 73 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -508,6 +508,79 @@ point.toString(); // (3,4,5)
508
508
| :--- |
509
509
| 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. |
510
510
511
+
#### Which Class?
512
+
513
+
You may need to determine in a constructor if that class is being instantiated directly, or being instantiated from a subclass with a `super()` call. We can use a special "pseudo property" `new.target`:
514
+
515
+
```js
516
+
classPoint2d {
517
+
// ..
518
+
519
+
constructor(x,y) {
520
+
if (new.target=== Point2) {
521
+
console.log("Constructing 'Point2d' instance");
522
+
}
523
+
}
524
+
525
+
// ..
526
+
}
527
+
528
+
classPoint3dextendsPoint2d {
529
+
// ..
530
+
531
+
constructor(x,y,z) {
532
+
super(x,y);
533
+
534
+
if (new.target=== Point3d) {
535
+
console.log("Constructing 'Point3d' instance");
536
+
}
537
+
}
538
+
539
+
// ..
540
+
}
541
+
542
+
var point =newPoint2d(3,4);
543
+
// Constructing 'Point2d' instance
544
+
545
+
var anotherPoint =newPoint3d(3,4,5);
546
+
// Constructing 'Point3d' instance
547
+
```
548
+
549
+
### But Which Kind Of Instance?
550
+
551
+
You may want to introspect a certain object instance to see if it's an instance of a specific class. We do this with the `instanceof` operator:
552
+
553
+
```js
554
+
classPoint2d { /* .. */ }
555
+
classPoint3dextendsPoint2d { /* .. */ }
556
+
557
+
var point =newPoint2d(3,4);
558
+
559
+
point instanceof Point2d; // true
560
+
point instanceof Point3d; // false
561
+
562
+
var anotherPoint =newPoint3d(3,4,5);
563
+
564
+
anotherPoint instanceof Point2d; // true
565
+
anotherPoint instanceof Point3d; // true
566
+
```
567
+
568
+
It may seem strange to see `anotherPoint instanceof Point2d` result in `true`. That's because `instanceof` is traversing the entire class inheritance hierarchy (the `[[Prototype]]` chain) until it finds a match.
569
+
570
+
If you instead wanted to check if the object instance was *only and directly* created by a certain class, check the instance's `constructor` property.
571
+
572
+
```js
573
+
point.constructor=== Point2d; // true
574
+
point.constructor=== Point3d; // false
575
+
576
+
anotherPoint.constructor=== Point2d; // false
577
+
anotherPoint.constructor=== Point3d; // true
578
+
```
579
+
580
+
| NOTE: |
581
+
| :--- |
582
+
| The `constructor` property shown here is *not* actually present on (owned) the `point` or `anotherPoint` instance objects. So where does it come from!? It's on each object's `[[Prototype]]` linked prototype object: `Point2d.prototype.constructor === Point2d` and `Point3d.prototype.constructor === Point3d`. |
583
+
511
584
### "Inheritance" Is Sharing, Not Copying
512
585
513
586
It may seem as if `Point3d`, when it `extends` the `Point2d` class, is in essence getting a *copy* of all the behavior defined in `Point2d`. Moreover, it may seem as if the concrete object instance `point` receives, *copied down* to it, all the methods from `Point3d` (and by extension, also from `Point2d`).
@@ -1068,4 +1141,3 @@ OK, we've laid out a bunch of disparate class features. I want to wrap up this c
1068
1141
// TODO
1069
1142
1070
1143
[^POLP]: *Principle of Least Privilege*, https://en.wikipedia.org/wiki/Principle_of_least_privilege, 15 July 2022.
0 commit comments