-
Notifications
You must be signed in to change notification settings - Fork 163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Differences between "normal" platform objects and "normal" JavaScript classes #226
Comments
No, typeof will always be object. You might be thinking about |
There has been talk of adding something to IDL to control enumerability, so on a technical level we can "solve" this. The more fundamental problem is the inconsistency in the platform and the lack of a credible plan to bridge it. :( ES classes are basically defined to look more like ES builtins here, while IDL standardized de-facto behavior of existing browser builtins like DOM. The web definitely depends on enumerability for some of the DOM APIs, but I don't know that anyone has a good list of which ones. Clearly we could make new ones non-enumerable, at the cost of even more confusion, but we could just as easily make new TC39 stuff enumerable, at the cost of even more confusion. Or maybe neither one is more confusing than what we have now, since most people have no clue which things are ES and which things are IDL-defined anyway. I don't see any non-sucky outcomes here, honestly...
In the sense that ES statics will examine their "this" object (the constructor object) for some state? We could quite trivially change this on the IDL side in the sense of passing the "this" object to the spec prose defining the IDL static, which would allow it to use it if it wants. In practice, there's typically nothing the spec prose wants out of that object, so the distinction is moot in most cases. In the specific case of URLSearchParams there are no statics to start with, so the distinction is even more moot. ;)
I'm not aware of anything like this.
The most obvious difference is that platform objects have branding checks and JS classes normally don't [1]. JS builtins, which are somewhat like JS clases in some ways and different in others, sometimes do and sometimes don't. [1] For the same reason they don't normally have interesting toString behavior: you can do it, but it takes some extra effort and most people wouldn't bother. |
Sorry, I meant instanceof, not typeof. |
@bzbarsky the URL object has a static defined in the File API (createObjectURL). |
The statics-being-methods thing mostly impacts whether they work when extracted or not. E.g. |
Ah. That's something that can be expressed in ES anyway using URL.createObjectURL and Promise.resolve are fundamentally different beasts: the former creates a string, while the latter creates a Promise. I agree that statics that create an object of the type being defined should be methods, to play nice with subclassing. With that in mind, we should change IDL to pass "this" to statics; if we don't have an existing issue on that, let's get one filed and just fix this. That will allow specs to do the right thing here. Whether we can change existing specs to the method semantics, I'm not sure. :( But I'm pretty sure this mostly (only?) affects statics that create an object of the type they're defined on. I just looked (well, had our binding codegen look) through Gecko's IDL looking for such statics. The full list is:
It's too bad no one raised this issue about statics when fetch's Response was being specified. :( IDB not raising it I'm not surprised by, of course; there weren't many ES-aware people involved in that. |
Oh, and looks like IDBLocaleAwareKeyRange is not even on by default yet... I can't speak to whether someone would want to subclass IDBKeyRange in practice, but subclassing Response seems like a totally reasonable thing to do. :( |
It would be really great if the standards venue didn't affect the shape of the resulting API. Sounds like the three things raised in this thread have a path towards resolution. Would it be reasonable to start a policy of doing things in a more ES-type style when new APIs come up (sounds like enumerability is the big one here)? For enumerability on the JS side, there seems to be a strong feeling in TC39 that we couldn't add more enumerable methods to existing objects without breaking existing code. |
Yes, it would, though we have a huge legacy of it having done just that. We had this exact conversation 4-5 years ago (not you and I, but various people involved in ES and web specs) and absolutely nothing changed as a result. :(
Why not in a more IDL-type style? Honest question, not trolling.
Oh, on the DOM side we can't remove enumerability from existing objects without breaking existing code. Or more precisely, we know there are some we can't remove it from, but we don't know which things are in that bucket, necessarily. This is all be a discussion about new things that are added; for existing stuff we're stuck with what we have, I'm afraid. |
@bzbarsky Definitely agree about not changing existing things.
The reason we don't make new things enumerable in ECMAScript (I believe) is that we're concerned about breaking the web. Maybe this claim that new enumerable properties the web would break isn't true, if other parts of the web platform have been getting away with it, but it makes me concerned. |
I think this claim is perhaps true for new properties added on existing objects, and especially on Array.prototype and Object.prototype, because those two would break a lot of for-in loops. I think adding enumerable stuff elsewhere would not have broken the web, and adding it on entirely new things is very unlikely to do so. |
This fixes https://www.w3.org/Bugs/Public/show_bug.cgi?id=28244, aligning Web IDL objects with the built-in ECMAScript objects (see #226), and updating the spec to match 1/4 browsers (Chrome) instead of 0/4 as it currently does.
(This issue could use the jsidl tag.) |
This fixes https://www.w3.org/Bugs/Public/show_bug.cgi?id=28244, aligning Web IDL objects with the built-in ECMAScript objects (see #226), and updates the spec to match 1/3 engines (Chromium) instead of 0/3 as it currently does.
This fixes https://www.w3.org/Bugs/Public/show_bug.cgi?id=28244, aligning Web IDL objects with the built-in ECMAScript objects (see #226), and updates the spec to match 1/3 engines (Chromium) instead of 0/3 as it currently does. The other two engines are willing to align, however! Tests: web-platform-tests/wpt#23140
This fixes https://www.w3.org/Bugs/Public/show_bug.cgi?id=28244, aligning Web IDL objects with the built-in ECMAScript objects (see #226), and updates the spec to match 1/3 engines (Chromium) instead of 0/3 as it currently does. The other two engines are willing to align, however! Tests: web-platform-tests/wpt#23140
Some are mentioned in tc39/proposals#30 (comment) by @domenic:
I believe in Gecko at least typeof will also be different.
This means for instance that https://streams.spec.whatwg.org/ cannot be done in IDL and that https://url.spec.whatwg.org/ expressed in TC39-language would have slightly different behavior.
That seems suboptimal, especially if there's still hope to eventually bridge the chasm somehow.
As a start, having it clearly documented how "normal" platform objects differ from "normal" JavaScript classes would be good.
The text was updated successfully, but these errors were encountered: