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
- X and Y are constructor functions, and
- Y is not the Object() constructor, and
- X.prototype has Y.prototype as its [[Prototype]] object Then
- X has Y as its [[Prototype]] object
For example, the above generalization holds for the following X,Y pairs
- HTMLElement, Element
- AggregateError, Error
- AsyncFunction, Function
- Node, EventTarget
- Element, Node
- RTCError, DOMException
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]]?
No, that is not a valid generalisation. It's common, but not ubiquituous. This pattern only started to appear since ES6
classes introduced the inheritance ofstaticproperties (including methods in particular) via the prototype chain. Until then, constructor functions were just plain functions, which inherited fromFunction.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
Errorhierarchy this was consciously introduced with ES6, in ES5.1 the native error constructors had still inherited fromFunction.prototype.For Web APIs, the Web IDL specification prescribes just this pattern for its interfaces:
constructorProtoberealm.[[Intrinsics]].[[%Function.prototype%]].Iinherits from some other interfaceP, then setconstructorPrototo the interface object ofPin realm.and
interfaceis declared to inherit from another interface, then setprototo the interface prototype object in realm of that inherited interface.prototorealm.[[Intrinsics]].[[%Object.prototype%]].Looking at those rules, there's actually a second exception: the
Windowconstructor inherits fromEventTarget, but theWindow.prototypeinherits from aWindowPropertiesobject (which in turn inherits fromEventTarget.prototype).No. There's a few likely explanations though:
DOMExceptionwas part of the first browser js implementations alreadynobody bothered to update itit's just an oversightEdit: Actually Web IDL explicitly describes it as an exception to the rule. It does not
inheritfromError, 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%.