arguments extending Array?

Lars T Hansen lth at acm.org
Fri Feb 2 16:03:46 PST 2007


> On Feb 2, 2007, at 10:52 AM, liorean wrote:
>
>> On 2/2/07, Hallvord R. M. Steen <hallvord at opera.com> wrote:
>>> In Opera's implementation the arguments object extends Array,
>>> meaning that
>>> it has all the Array-related methods and also methods and
>>> properties set
>>> on Array.prototype . This has caused an incompatibility with a
>>> recent RC
>>> of Prototype and is considered a bug - but from blog and E-mail
>>> correspondence regarding this issue it seems several[1] authors
>>> consider
>>> it a nice feature. The arguments object is already "array-like"
>>> and apart
>>>  from the Prototype issue our implementation has caused us no known
>>> problems (the workaround for Prototype is relatively simple and
>>> they have
>>> already implemented it AFAIK).
>>
>> I think it's among the most wanted features for adding to the
>> language. And Prototype has gotten a lot of criticism for breaking
>> Array objects. (Including from me...)
>
> See the first bullet at http://developer.mozilla.org/es4/proposals/
> bug_fixes.html -- ES4 indeed proposes to make arguments objects
> delegate to Array.prototype.
>
>>
>>> Would it be an idea for ES4 to make arguments extend Array?
>>
>> It's a wanted feature, but not necessarily a good one to add as-is.
>> For example, formal parameters are joined with their corresponding
>> number in arguments. Change either and both are changed. So something
>> like this: arguments.sort(function()(Math.random()-.5)) would do evil
>> things with formal parameter values.
>
> It's true that arguments[i] aliases the i'th formal parameter for i <
> (number of formals declared). But you can do confusing things via
> this aliasing by mutation already, and could since JS1 in 1995.
> Delegating to Array.prototype does not change anything except by
> adding convenience, which will be used for good more than for ill, we
> believe.
>
> All tools can be misused. If the bug here is the aliasing, then it's
> too late to fix without breaking backward compatibility, and we do
> not propose to do that for arguments[i] aliasing the i'th formal.

Speaking of that aliasing mechanism...

In principle we ought we to be able to express this aliasing by an
implementation of an arguments object in terms of plainer objects with
getters and setters.  I am thinking that

   function f(a,b) {
      ...
   }

is really something along the lines of

   function f(a,b) {
      var arguments = [ get 0() { return a },
                        set 0(v) { a = v },
                        get 1() { return b },
                        set 1(v) { b = v } ];
      ...
   }

(Glossing over several special cases here and ignoring the fact that [...]
does not accomodate getters and setters (?).)  I know a fast
implementation would not do it this way, but as a specification it would
make things very clear, all behavior would follow from more general rules.

--lars




More information about the Es4-discuss mailing list