- From: Darien Maillet Valentine <notifications@github.com>
- Date: Fri, 25 Feb 2022 06:05:36 -0800
- To: whatwg/webidl <webidl@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/webidl/issues/1107@github.com>
The [custom bindings for DOMException](https://webidl.spec.whatwg.org/#es-DOMException-specialness) specify that DOMException.prototype.[[Prototype]] is %Error.prototype%. However it doesn’t also set DOMException.[[Prototype]] to %Error%, so instead it ends up with %Function.prototype%, which is what would occur for a “base” constructor. This seems to make DOMException a pretty peculiar outlier. Among ECMAScript intrinsics, there are no cases where F.prototype.[[Prototype]] and F.[[Prototype]].prototype both exist yet point at different values. In Web IDL, this does also occur with `[LegacyFactoryFunction]` but in these cases, F.prototype.constructor isn’t F (and does exhibit the normal pattern), so it’s relatively tough to run into the difference. In any case, scanning for it among globals suggests that DOMException’s constructor-prototype relationship is likely a true one-off: ![console screenshot. the code in the screenshot follows as text](https://user-images.githubusercontent.com/6257356/155726911-02c6ccad-19b6-419c-b9ae-e7735e9b1c50.png) <details> <summary>(code from image)</summary> ```js let i = 0; for (let key of Object.getOwnPropertyNames(globalThis).sort()) { let { value } = Object.getOwnPropertyDescriptor(globalThis, key); if (typeof value === "function" && value.prototype) { let cp = Object.getPrototypeOf(value); let pp = Object.getPrototypeOf(value.prototype); let isDerived = pp && pp !== Object.prototype; if (isDerived && value.prototype.constructor !== value) { console.warn(`${ key } is weird, but in a [LegacyFactoryFunction] way`); } else if (isDerived && cp !== pp.constructor) { console.error(`${ key } is (uniquely) weird!`); } else { i++; } } } console.log(`[${ i } other objects looked like normal constructors]`); // In Firefox, this printed: // Audio is weird, but in a [LegacyFactoryFunction] way // DOMException is (uniquely) weird! // Image is weird, but in a [LegacyFactoryFunction] way // Option is weird, but in a [LegacyFactoryFunction] way // [595 other objects looked like normal constructors] ``` </details> Among other quirks, this means `Error[@@hasInstance]` and `Error.isPrototypeOf` tell unexpectedly different stories about the relationship between Error and DOMException. ```js console.log(new EvalError instanceof Error); // true console.log(Error.isPrototypeOf(EvalError)); // true console.log(Error.isPrototypeOf(new EvalError().constructor)); // true console.log(new DOMException instanceof Error); // true console.log(Error.isPrototypeOf(DOMException)); // false console.log(Error.isPrototypeOf(new DOMException().constructor)); // false ``` Is DOMExceptions departure from the typical prototype inheritance pattern intentional? It seems like the sort of thing that could plausibly have been necessitated by a web compat issue, but I didn’t turn up any history on it, and it also seems plausible that it was an oversight and actually should be specified to inherit from %Error%. -- Reply to this email directly or view it on GitHub: https://github.com/whatwg/webidl/issues/1107 You are receiving this because you are subscribed to this thread. Message ID: <whatwg/webidl/issues/1107@github.com>
Received on Friday, 25 February 2022 14:05:48 UTC