[whatwg/streams] Constructor specification is unclear (#965)

Is subclassing supposed to work?

```js
class SpamStream extends ReadableStream {
    constructor() {
        let stream;
        super({
            pull(controller) {
                controller.enqueue("spam");
                stream.spamCount++;
            }
        });
        this.spamCount = 0;
        stream = this;
    }
    hasSpammed() { return this.spamCount > 0; }
}

new SpamStream().hasSpammed()
```

The standard currently says:

>  We prefix section headings with `new` to indicate they are defining constructors; when doing so, we assume that NewTarget will be checked before the algorithm starts.

What it doesn't say is how **this** gets initialized. Mozilla's current implementation ignores NewTarget and always creates an object whose [[Prototype]] is the original value of ReadableStream.prototype. So the above code would fail; `hasSpammed` would not be on that object's prototype chain.

I think we want something like

> 1. If NewTarget is **undefined**, throw a **TypeError** exception.
> 2. Let **this** be ? OrdinaryCreateFromConstructor(NewTarget, the name of the per-realm intrinsic object that is this class's original prototype, the List of this class's internal slots).

(Technically, this doesn't quite work, because OrdinaryCreateFromConstructor step 1 effectively asserts that it is being called from inside ECMA-262 and not from other standards. But I think it's an improvement anyway.)


-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/streams/issues/965

Received on Tuesday, 20 November 2018 14:34:47 UTC