In other words, why isn't DOMException like AggregateError, EvalError, etc?
Both expressions evaluate to true:
Object.getPrototypeOf(DOMException) === Function.prototype
Object.getPrototypeOf(DOMException.prototype) === Error.prototype
I used to think the following generalization has no counterexamples:
If
For example, the above generalization holds for the following X,Y pairs
The only case I know of in which the generalization fails is when X = DOMException and Y = Error.
Is there a deeper reason why the DOMException constructor itself cannot have the Error constructor as its [[Prototype]]?
If
X.prototype
hasY.prototype
as its [[Prototype]] object,
ThenX
hasY
as its [[Prototype]] object
No, that is not a valid generalisation. It's common, but not ubiquituous. This pattern only started to appear since ES6 class
es introduced the inheritance of static
properties (including methods in particular) via the prototype chain. Until then, constructor functions were just plain functions, which inherited from Function.prototype
. Many libraries still do this.
However, it's true that this generalisation holds for nearly all builtin classes, both native ones (defined by ECMAScript) and host-provided ones (like the DOM). For the Error
hierarchy this was consciously introduced with ES6, in ES5.1 the native error constructors had still inherited from Function.prototype
.
For Web APIs, the Web IDL specification prescribes just this pattern for its interfaces:
constructorProto
be realm
.[[Intrinsics]].[[%Function.prototype%]].I
inherits from some other interface P
, then set constructorProto
to the interface object of P
in realm.and
interface
is declared to inherit from another interface, then set proto
to the interface prototype object in realm of that inherited interface.proto
to realm
.[[Intrinsics]].[[%Object.prototype%]].Looking at those rules, there's actually a second exception: the Window
constructor inherits from EventTarget
, but the Window.prototype
inherits from a WindowProperties
object (which in turn inherits from EventTarget.prototype
).
Is there a deeper reason why the
DOMException
constructor itself cannot have theError
constructor as its [[Prototype]]?
No. There's a few likely explanations though:
DOMException
was part of the first browser js implementations alreadyEdit: Actually Web IDL explicitly describes it as an exception to the rule. It does not inherit
from Error
, but it still "has its [[Prototype]] internal slot set to the intrinsic object %Error.prototype%
". This was discussed in issue #55 and changed in PR #378 to align with the implementation reality - away from the previously described [[Prototype]] value of %Error%
.