Mark S. Miller wrote:
> 1) Where is the semantic state that distinguishes magic arguments from other
> array-like non-arrays that inherit from Array.prototype? There needs to be
> such semantic state, to account for the acceptability of arguments as the
> second argument of Function.prototype.apply, to whit:
>
> (From 15.3.4.3 of 22dec08 draft)
>> Otherwise, if argArray is neither an array nor an arguments object (see
> 10.3.2),
>> a TypeError exception is thrown. If argArray is either an array or an
> arguments
>> object, [...]
That can be fixed by making Function.prototype.apply accept any array-like
object (i.e. only read the .length and array index properties of argArray).
I've previously suggested wording for that, which is repeated at the end
of this email.
> 2) What happens when you freeze an arguments object?
I don't think this presents any problem: the synthesized getter/setter
properties are made non-[[Configurable]] and the object is made
non-[[Extensible]], just like when freezing any other object.
> In the Kona draft (and still in the 22dec08 draft), the joining of
> non-strict arguments with the parameter variables is specified by
> synthesizing getter/setter functions. At the Kona meeting, Waldemar (I
> think) pointed out 1) that the way this was specified had inadvertent
> non-hygienic lexical variable capture problems,
Why is it non-hygienic? It captures the variables, certainly, but it's
supposed to.
> and 2) given the new
> attribute revelation APIs, such explanatory getters and setters could be
> reified, requiring us to specify whether they're frozen, when they're ===,
> etc.
Seems fine to me. Don't we *have* to specify what attributes they have?
An arguments object should not be a magical special case for attribute
reflection. The behaviour of === is already clear in the 22 December draft,
because it specifies that the getters/setters are initialized as-if by
creating new functions.
> 3) What happens when you write to an object that inherits from an arguments
> object?
>
> Given
> var sub = Object.create(arguments);
> sub[3] = foo;
>
> does this assignment modify the parameter variable joined to arguments[3]?
> Once again, if we think of arguments[3] as a data property, then the answer
> should be no.
(Non-strict) arguments properties are not data properties, period. They
can't be because that would not result in the required aliasing with
parameters.
> We've instead created a new own '3' property on sub and have
> not affected its parent. But if we think of it as an accessor property, then
> this assignment should invoke the inherited setter.
Right. This is arguably a little bit overspecified, but mostly harmless.
> Whatever we do with strict arguments, we need to answer all three of these
> questions for non-strict arguments anyway.
I agree; I just think the current wording already does answer these --
subject to the Function.prototype.apply fix below, which is independently
useful.
There should be a Trac issue for Function.prototype.apply; I'll be busy
for the next couple of days, so feel free to add one.
----
The following changes
- make apply handle its argArray generically;
- rewrite apply and call using the algorithm notation;
- clarify that apply and call return the return value of the called
function;
- acknowledge that there may be an implementation-defined limit on
the number of arguments to a function. (This also needs to be fixed
in section 11.2.4.)
====
15.3.4.3 Function.prototype.apply (thisArg, argArray)
The apply method takes two arguments, thisArg and argArray, and performs
a function call using the [[Call]] property of the this object, by the
following steps:
1. If IsCallable(this) is false, then throw a TypeError exception.
2. If argArray is null or undefined, then
a. Call the [[Call]] method of this object, providing thisArg
as the this value and no arguments.
b. Return Result(2a).
3. If Type(argArray) is not Object, then throw a TypeError exception.
4. Call the [[Get]] method of argArray with property name "length".
5. Let n be ToArrayLength(Result(4)).
6. If n is greater than an implementation-defined limit on the number
of arguments to a function, then throw a RangeError exception.
7. For every nonnegative integer k less than n:
a. Let P_k be ToString(k).
b. Let arg_k be the result of calling the [[Get]] method of
argArray with property name P_k.
8. Call the [[Call]] method of this object, providing thisArg as the
this value and arg_0, arg_1, ... arg_{n-1} as the arguments.
9. Return Result(8).
The length property of the apply method is 2.
15.3.4.4 Function.prototype.call (thisArg [ , arg_0 [ , arg_1, ... ] ] )
The call method takes one or more arguments, thisArg and (optionally)
arg_0, arg_1 etc., and performs a function call using the [[Call]]
property of the object, by the following steps:
1. If IsCallable(this) is false, then throw a TypeError exception.
2. Call the [[Call]] method of this object, providing thisArg as the
this value, and any remaining arguments to the call method starting
with arg_0 (if provided) as the arguments.
3. Return Result(2).
The length property of the call method is 1.
====
--
David-Sarah Hopwood ⚥
_______________________________________________
Es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss