3 ms·
Oh, and: The JS spec defines callability indirectly. There's this notion of "internal properties" (i.e., fictional properties that some objects have and some la
by gjm11 17y ago
Oh, and: The JS spec defines callability indirectly. There's this notion of "internal properties" (i.e., fictional properties that some objects have and some lack) and "abstract operations" (i.e., fictional functions defined on JS objects) and the spec often says things like "Such-and-such a function tests for internal property [[Foo]] and then invokes abstract operation Bar".
So, what happens when you say "f()" in JavaScript? It's defined in terms of an abstract operation called IsCallable and an internal property called [[Call]]. IsCallable, in turn, is defined as "has the [[Call]] internal property". The spec specifies, e.g., that when you define a function the resulting object has [[Call]], and that numbers don't have [[Call]].
But it never says any of the following: (1) "RegExp objects have [[Call]]". (2) "Regexp objects do not have [[Call]]". (3) "Nothing has [[Call]] unless this spec says it does". (4) "When this spec doesn't say whether an object has [[Call]], it's up to each implementation whether it does." For some other internal properties there is a clause like (3), but not for [[Call]].
Which means that it's debatable whether making regexps callable is permitted by the spec (I think it is), but (I think) it's clear that if regexps are callable then they must be treated as having [[Call]], which means that they should not be serialized. But I am not a JS expert, and you should take the above with a grain of salt.
- ars 17y agoThat's a good summary. IMO just because a regex is callable does not mean it should be omitted (despite the spec). If it can be serialized in a proper way then go ahead. (I know it has other properties, but just emitting /foo/ would be fine with me.) A RegExp is probably a special case. The browsers should do the useful thing, and request an errata on the spec. Wait, are they talking about the global RegExp object, or a specific RegExp? And they should fork this bug into one just about RegExp.
- kangax 17y agoThey are talking about any `RegExp` object (technically, any object with "RegExp" [[Class]])
- gjm11 17y agoSerializing a regexp as, say, "/foo/" would mean emitting alleged JSON that doesn't conform to the JSON grammar in the spec, and that existing JSON parsers might be completely unable to do anything with. It might make some sense to change the spec to include regexp literals, but while the spec says what it does it would be unresponsible for any browser's stringify implementation to emit things that others' parse implementations might barf on. (It's a pity that JSON isn't more easily extensible in a backward-compatible manner. On the other hand, it's not clear how that could have been enabled without breaking the it's-just-a-subset-of-JS-literal-syntax principle.)
- kangax 17y ago> Which means that it's debatable whether making regexps callable is permitted by the spec [...] Unfortunately (or fortunately, depending on how you look at it) it is perfectly permitted in at least ES3. See my comment on webkit's bugtracker - https://bugs.webkit.org/show_bug.cgi?id=28117#c19 https://bugs.webkit.org/show_bug.cgi?id=28117#c19
- gjm11 17y agoI'm not fully convinced. The bit of spec you quote says that implementations can add "properties not described in this specification, and values for those properties, for objects that are described in this specification", which I take to mean that you can add properties that the spec doesn't mention, not that you can add properties that the spec does mention and doesn't say those objects have. And "internal properties" are not really properties, which makes it even less clear that that language gives licence for an implementation to add them to objects they aren't specified for. (I do still think the spec should be interpreted as making regexps callable, but only because it doesn't explicitly say that implementations aren't allowed to decide for themselves about internal properties whose existence and/or value is left unspecified in the spec.)
- kangax 17y agoYes, there's clearly an ambiguity in section 2 with regards to internal properties. Looking at "Internal Properties and Methods" section (8.6.2), you can see that specification makes it pretty clear that, for example, host objects' behavior is completely implementation-dependent: host objects are allowed to "spoof" [[Class]] values (which they, in fact, do in real life); that [[DefaultValue]] can go as far as throwing an error; that [[Get]], [[Put]] and [[HasProperty]] do not have to necessarily match; and that they don't have to implement any or all of the internal methods at all. But that's host objects, and we are talking about built-ins, so there's no proof there. I guess my point is that specs usually tend to state important things explicitly (using somewhat unambiguous keywords like "must" or "should"). You can see it in that same 8.6.2 section: | Every object (including host objects) must implement the | [[Prototype]] and [[Class]] properties and the [[Get]], | [[Put]], [[CanPut]], [[HasProperty]], [[Delete]], and | [[DefaultValue]] methods. Might be worth bringing this up on es-discuss/es5-discuss mailing lists.